Move xfa_basic_imp to cxfa_widetextread.

This Cl splits out the CXFA_WideTextRead class into it's own file. The helper
methods have been moved into xfa_utils.cpp and their pre-declarations into
xfa_utils.h.

Review-Url: https://codereview.chromium.org/2165993002
diff --git a/BUILD.gn b/BUILD.gn
index f824163..996f7be 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1383,6 +1383,8 @@
       "xfa/fxfa/parser/cxfa_line.h",
       "xfa/fxfa/parser/cxfa_margin.cpp",
       "xfa/fxfa/parser/cxfa_margin.h",
+      "xfa/fxfa/parser/cxfa_measurement.cpp",
+      "xfa/fxfa/parser/cxfa_measurement.h",
       "xfa/fxfa/parser/cxfa_node.cpp",
       "xfa/fxfa/parser/cxfa_nodehelper.cpp",
       "xfa/fxfa/parser/cxfa_nodehelper.h",
@@ -1416,6 +1418,8 @@
       "xfa/fxfa/parser/cxfa_value.h",
       "xfa/fxfa/parser/cxfa_valuearray.cpp",
       "xfa/fxfa/parser/cxfa_valuearray.h",
+      "xfa/fxfa/parser/cxfa_widetextread.cpp",
+      "xfa/fxfa/parser/cxfa_widetextread.h",
       "xfa/fxfa/parser/cxfa_widgetdata.cpp",
       "xfa/fxfa/parser/cxfa_widgetdata.h",
       "xfa/fxfa/parser/cxfa_xml_parser.cpp",
@@ -1428,8 +1432,6 @@
       "xfa/fxfa/parser/xfa_basic_data_element_script.cpp",
       "xfa/fxfa/parser/xfa_basic_data_enum.cpp",
       "xfa/fxfa/parser/xfa_basic_data_packets.cpp",
-      "xfa/fxfa/parser/xfa_basic_imp.cpp",
-      "xfa/fxfa/parser/xfa_basic_imp.h",
       "xfa/fxfa/parser/xfa_doclayout.h",
       "xfa/fxfa/parser/xfa_document.h",
       "xfa/fxfa/parser/xfa_document_datamerger_imp.cpp",
diff --git a/testing/libfuzzer/pdf_cfx_saxreader_fuzzer.cc b/testing/libfuzzer/pdf_cfx_saxreader_fuzzer.cc
index 54cc410..501c4ff 100644
--- a/testing/libfuzzer/pdf_cfx_saxreader_fuzzer.cc
+++ b/testing/libfuzzer/pdf_cfx_saxreader_fuzzer.cc
@@ -6,13 +6,13 @@
 
 #include "xfa/fde/xml/cfx_saxreader.h"
 #include "xfa/fgas/crt/fgas_stream.h"
-#include "xfa/fxfa/parser/xfa_utils.h"
+#include "xfa/fxfa/parser/cxfa_widetextread.h"
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   CFX_WideString input = CFX_WideString::FromUTF8(
       CFX_ByteStringC(data, static_cast<FX_STRSIZE>(size)));
   std::unique_ptr<IFX_Stream, ReleaseDeleter<IFX_Stream>> stream(
-      XFA_CreateWideTextRead(input));
+      new CXFA_WideTextRead(input));
   if (!stream)
     return 0;
 
diff --git a/testing/libfuzzer/pdf_css_fuzzer.cc b/testing/libfuzzer/pdf_css_fuzzer.cc
index da8b1f5..a893858 100644
--- a/testing/libfuzzer/pdf_css_fuzzer.cc
+++ b/testing/libfuzzer/pdf_css_fuzzer.cc
@@ -8,7 +8,7 @@
 #include "xfa/fde/css/fde_css.h"
 #include "xfa/fde/css/fde_csssyntax.h"
 #include "xfa/fgas/crt/fgas_stream.h"
-#include "xfa/fxfa/parser/xfa_utils.h"
+#include "xfa/fxfa/parser/cxfa_widetextread.h"
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   CFDE_CSSSyntaxParser parser;
@@ -16,7 +16,7 @@
   CFX_WideString input = CFX_WideString::FromUTF8(
       CFX_ByteStringC(data, static_cast<FX_STRSIZE>(size)));
   std::unique_ptr<IFX_Stream, ReleaseDeleter<IFX_Stream>> stream(
-      XFA_CreateWideTextRead(input));
+      new CXFA_WideTextRead(input));
   if (!stream)
     return 0;
 
diff --git a/testing/libfuzzer/pdf_xml_fuzzer.cc b/testing/libfuzzer/pdf_xml_fuzzer.cc
index 0b80b1a..c871999 100644
--- a/testing/libfuzzer/pdf_xml_fuzzer.cc
+++ b/testing/libfuzzer/pdf_xml_fuzzer.cc
@@ -11,7 +11,7 @@
 #include "core/fxcrt/include/fx_system.h"
 #include "xfa/fde/xml/fde_xml_imp.h"
 #include "xfa/fxfa/parser/cxfa_xml_parser.h"
-#include "xfa/fxfa/parser/xfa_utils.h"
+#include "xfa/fxfa/parser/cxfa_widetextread.h"
 
 namespace {
 
@@ -51,7 +51,7 @@
   CFX_WideString input = CFX_WideString::FromUTF8(
       CFX_ByteStringC(data, static_cast<FX_STRSIZE>(size)));
   std::unique_ptr<IFX_Stream, ReleaseDeleter<IFX_Stream>> stream(
-      XFA_CreateWideTextRead(input));
+      new CXFA_WideTextRead(input));
   if (!stream)
     return 0;
 
diff --git a/xfa.gyp b/xfa.gyp
index 6309965..72e2922 100644
--- a/xfa.gyp
+++ b/xfa.gyp
@@ -488,6 +488,8 @@
         "xfa/fxfa/parser/cxfa_line.h",
         "xfa/fxfa/parser/cxfa_margin.cpp",
         "xfa/fxfa/parser/cxfa_margin.h",
+        "xfa/fxfa/parser/cxfa_measurement.cpp",
+        "xfa/fxfa/parser/cxfa_measurement.h",
         "xfa/fxfa/parser/cxfa_node.cpp",
         "xfa/fxfa/parser/cxfa_nodehelper.cpp",
         "xfa/fxfa/parser/cxfa_nodehelper.h",
@@ -521,6 +523,8 @@
         "xfa/fxfa/parser/cxfa_value.h",
         "xfa/fxfa/parser/cxfa_valuearray.cpp",
         "xfa/fxfa/parser/cxfa_valuearray.h",
+        "xfa/fxfa/parser/cxfa_widetextread.cpp",
+        "xfa/fxfa/parser/cxfa_widetextread.h",
         "xfa/fxfa/parser/cxfa_widgetdata.cpp",
         "xfa/fxfa/parser/cxfa_widgetdata.h",
         "xfa/fxfa/parser/cxfa_xml_parser.cpp",
@@ -533,8 +537,6 @@
         "xfa/fxfa/parser/xfa_basic_data_enum.cpp",
         "xfa/fxfa/parser/xfa_basic_data_packets.cpp",
         "xfa/fxfa/parser/xfa_basic_data.h",
-        "xfa/fxfa/parser/xfa_basic_imp.cpp",
-        "xfa/fxfa/parser/xfa_basic_imp.h",
         "xfa/fxfa/parser/xfa_doclayout.h",
         "xfa/fxfa/parser/xfa_document.h",
         "xfa/fxfa/parser/xfa_document_datamerger_imp.cpp",
diff --git a/xfa/fxfa/app/xfa_ffwidgethandler.cpp b/xfa/fxfa/app/xfa_ffwidgethandler.cpp
index 8e2b9df..5b2577b 100644
--- a/xfa/fxfa/app/xfa_ffwidgethandler.cpp
+++ b/xfa/fxfa/app/xfa_ffwidgethandler.cpp
@@ -14,6 +14,7 @@
 #include "xfa/fxfa/include/xfa_ffdoc.h"
 #include "xfa/fxfa/include/xfa_ffdocview.h"
 #include "xfa/fxfa/include/xfa_ffwidget.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
 #include "xfa/fxfa/parser/xfa_document_layout_imp.h"
 
 CXFA_FFWidgetHandler::CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView)
diff --git a/xfa/fxfa/app/xfa_textlayout.cpp b/xfa/fxfa/app/xfa_textlayout.cpp
index 6643d92..88645b7 100644
--- a/xfa/fxfa/app/xfa_textlayout.cpp
+++ b/xfa/fxfa/app/xfa_textlayout.cpp
@@ -20,6 +20,7 @@
 #include "xfa/fxfa/include/xfa_ffapp.h"
 #include "xfa/fxfa/include/xfa_ffdoc.h"
 #include "xfa/fxfa/include/xfa_fontmgr.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
 
 CXFA_CSSTagProvider::CXFA_CSSTagProvider()
     : m_bTagAvailable(FALSE), m_bContent(FALSE) {}
diff --git a/xfa/fxfa/include/fxfa_basic.h b/xfa/fxfa/include/fxfa_basic.h
index 2a37973..c4dcfca 100644
--- a/xfa/fxfa/include/fxfa_basic.h
+++ b/xfa/fxfa/include/fxfa_basic.h
@@ -96,10 +96,6 @@
   uint32_t eFlags;
 };
 
-const XFA_PACKETINFO* XFA_GetPacketByName(const CFX_WideStringC& wsName);
-const XFA_PACKETINFO* XFA_GetPacketByID(uint32_t dwPacket);
-const XFA_PACKETINFO* XFA_GetPacketByIndex(XFA_PACKET ePacket);
-
 enum XFA_ATTRIBUTEENUM {
   XFA_ATTRIBUTEENUM_Asterisk,
   XFA_ATTRIBUTEENUM_Slash,
@@ -938,9 +934,6 @@
   XFA_ObjectType eObjectType;
 };
 
-XFA_Element XFA_GetElementTypeForName(const CFX_WideStringC& wsName);
-const XFA_ELEMENTINFO* XFA_GetElementByID(XFA_Element eName);
-
 enum XFA_ATTRIBUTETYPE {
   XFA_ATTRIBUTETYPE_NOTSURE,
   XFA_ATTRIBUTETYPE_Enum,
@@ -958,25 +951,6 @@
   void* pDefValue;
 };
 
-const XFA_ATTRIBUTEINFO* XFA_GetAttributeByName(const CFX_WideStringC& wsName);
-const XFA_ATTRIBUTEINFO* XFA_GetAttributeByID(XFA_ATTRIBUTE eName);
-FX_BOOL XFA_GetAttributeDefaultValue(void*& pValue,
-                                     XFA_Element eElement,
-                                     XFA_ATTRIBUTE eAttribute,
-                                     XFA_ATTRIBUTETYPE eType,
-                                     uint32_t dwPacket);
-XFA_ATTRIBUTEENUM XFA_GetAttributeDefaultValue_Enum(XFA_Element eElement,
-                                                    XFA_ATTRIBUTE eAttribute,
-                                                    uint32_t dwPacket);
-CFX_WideStringC XFA_GetAttributeDefaultValue_Cdata(XFA_Element eElement,
-                                                   XFA_ATTRIBUTE eAttribute,
-                                                   uint32_t dwPacket);
-FX_BOOL XFA_GetAttributeDefaultValue_Boolean(XFA_Element eElement,
-                                             XFA_ATTRIBUTE eAttribute,
-                                             uint32_t dwPacket);
-CXFA_Measurement XFA_GetAttributeDefaultValue_Measure(XFA_Element eElement,
-                                                      XFA_ATTRIBUTE eAttribute,
-                                                      uint32_t dwPacket);
 struct XFA_ELEMENTHIERARCHY {
   uint16_t wStart;
   uint16_t wCount;
@@ -990,11 +964,6 @@
   int16_t wParentIndex;
 };
 
-const uint8_t* XFA_GetElementAttributes(XFA_Element eElement, int32_t& iCount);
-
-const XFA_ATTRIBUTEINFO* XFA_GetAttributeOfElement(XFA_Element eElement,
-                                                   XFA_ATTRIBUTE eAttribute,
-                                                   uint32_t dwPacket);
 #define XFA_PROPERTYFLAG_OneOf 0x01
 #define XFA_PROPERTYFLAG_DefaultOneOf 0x02
 struct XFA_PROPERTY {
@@ -1002,19 +971,13 @@
   uint8_t uOccur;
   uint8_t uFlags;
 };
-const XFA_PROPERTY* XFA_GetElementProperties(XFA_Element eElement,
-                                             int32_t& iCount);
-const XFA_PROPERTY* XFA_GetPropertyOfElement(XFA_Element eElement,
-                                             XFA_Element eProperty,
-                                             uint32_t dwPacket);
+
 struct XFA_ATTRIBUTEENUMINFO {
   uint32_t uHash;
   const FX_WCHAR* pName;
   XFA_ATTRIBUTEENUM eName;
 };
-const XFA_ATTRIBUTEENUMINFO* XFA_GetAttributeEnumByName(
-    const CFX_WideStringC& wsName);
-const XFA_ATTRIBUTEENUMINFO* XFA_GetAttributeEnumByID(XFA_ATTRIBUTEENUM eName);
+
 enum XFA_UNIT {
   XFA_UNIT_Unknown,
   XFA_UNIT_Percent,
@@ -1027,30 +990,12 @@
   XFA_UNIT_Mm,
   XFA_UNIT_Mp,
 };
-class CXFA_Measurement {
- public:
-  void Set(const CFX_WideStringC& wsMeasure);
-  void Set(FX_FLOAT fValue, XFA_UNIT eUnit) {
-    m_fValue = fValue;
-    m_eUnit = eUnit;
-  }
 
-  XFA_UNIT GetUnit() const { return m_eUnit; }
-  FX_FLOAT GetValue() const { return m_fValue; }
-  FX_BOOL ToString(CFX_WideString& wsMeasure) const;
-  FX_BOOL ToUnit(XFA_UNIT eUnit, FX_FLOAT& fValue) const;
-  FX_FLOAT ToUnit(XFA_UNIT eUnit) const {
-    FX_FLOAT f;
-    return ToUnit(eUnit, f) ? f : 0;
-  }
-  CXFA_Measurement() { Set(-1, XFA_UNIT_Unknown); }
-  CXFA_Measurement(const CFX_WideStringC& wsMeasure) { Set(wsMeasure); }
-  CXFA_Measurement(FX_FLOAT fValue, XFA_UNIT eUnit) { Set(fValue, eUnit); }
-  static XFA_UNIT GetUnit(const CFX_WideStringC& wsUnit);
-
- protected:
-  FX_FLOAT m_fValue;
-  XFA_UNIT m_eUnit;
+struct XFA_NOTSUREATTRIBUTE {
+  XFA_Element eElement;
+  XFA_ATTRIBUTE eAttribute;
+  XFA_ATTRIBUTETYPE eType;
+  void* pValue;
 };
 
 class CFXJSE_Arguments;
@@ -1063,8 +1008,6 @@
   XFA_METHOD_CALLBACK lpfnCallback;
 };
 
-const XFA_METHODINFO* XFA_GetMethodByName(XFA_Element eElement,
-                                          const CFX_WideStringC& wsMethodName);
 typedef void (CXFA_Object::*XFA_ATTRIBUTE_CALLBACK)(CFXJSE_Value* pValue,
                                                     FX_BOOL bSetting,
                                                     XFA_ATTRIBUTE eAttribute);
@@ -1079,8 +1022,5 @@
   int32_t eAttribute;
   uint16_t eValueType;
 };
-const XFA_SCRIPTATTRIBUTEINFO* XFA_GetScriptAttributeByName(
-    XFA_Element eElement,
-    const CFX_WideStringC& wsAttributeName);
 
 #endif  // XFA_FXFA_INCLUDE_FXFA_BASIC_H_
diff --git a/xfa/fxfa/parser/cscript_layoutpseudomodel.cpp b/xfa/fxfa/parser/cscript_layoutpseudomodel.cpp
index 10bfd6d..fe504c4 100644
--- a/xfa/fxfa/parser/cscript_layoutpseudomodel.cpp
+++ b/xfa/fxfa/parser/cscript_layoutpseudomodel.cpp
@@ -11,6 +11,7 @@
 #include "fxjs/include/cfxjse_arguments.h"
 #include "third_party/base/stl_util.h"
 #include "xfa/fxfa/app/xfa_ffnotify.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
 #include "xfa/fxfa/parser/cxfa_scriptcontext.h"
 #include "xfa/fxfa/parser/xfa_doclayout.h"
 #include "xfa/fxfa/parser/xfa_document.h"
diff --git a/xfa/fxfa/parser/cxfa_box.cpp b/xfa/fxfa/parser/cxfa_box.cpp
index 95b247a..3204ab0 100644
--- a/xfa/fxfa/parser/cxfa_box.cpp
+++ b/xfa/fxfa/parser/cxfa_box.cpp
@@ -7,6 +7,7 @@
 #include "xfa/fxfa/parser/cxfa_box.h"
 
 #include "xfa/fxfa/parser/cxfa_corner.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
 #include "xfa/fxfa/parser/xfa_object.h"
 
 namespace {
diff --git a/xfa/fxfa/parser/cxfa_caption.cpp b/xfa/fxfa/parser/cxfa_caption.cpp
index 6606d51..7f9e88e 100644
--- a/xfa/fxfa/parser/cxfa_caption.cpp
+++ b/xfa/fxfa/parser/cxfa_caption.cpp
@@ -6,6 +6,7 @@
 
 #include "xfa/fxfa/parser/cxfa_caption.h"
 
+#include "xfa/fxfa/parser/cxfa_measurement.h"
 #include "xfa/fxfa/parser/xfa_object.h"
 
 CXFA_Caption::CXFA_Caption(CXFA_Node* pNode) : CXFA_Data(pNode) {}
diff --git a/xfa/fxfa/parser/cxfa_data.cpp b/xfa/fxfa/parser/cxfa_data.cpp
index 0589adf..75ec09c 100644
--- a/xfa/fxfa/parser/cxfa_data.cpp
+++ b/xfa/fxfa/parser/cxfa_data.cpp
@@ -7,6 +7,7 @@
 #include "xfa/fxfa/parser/cxfa_data.h"
 
 #include "core/fxcrt/include/fx_ext.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
 #include "xfa/fxfa/parser/xfa_object.h"
 
 // Static.
diff --git a/xfa/fxfa/parser/cxfa_font.cpp b/xfa/fxfa/parser/cxfa_font.cpp
index 8d3e785..52d12bb 100644
--- a/xfa/fxfa/parser/cxfa_font.cpp
+++ b/xfa/fxfa/parser/cxfa_font.cpp
@@ -8,6 +8,7 @@
 
 #include "core/fxge/include/fx_dib.h"
 #include "xfa/fxfa/parser/cxfa_fill.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
 #include "xfa/fxfa/parser/xfa_object.h"
 
 CXFA_Font::CXFA_Font(CXFA_Node* pNode) : CXFA_Data(pNode) {}
diff --git a/xfa/fxfa/parser/cxfa_measurement.cpp b/xfa/fxfa/parser/cxfa_measurement.cpp
new file mode 100644
index 0000000..7c6db2e
--- /dev/null
+++ b/xfa/fxfa/parser/cxfa_measurement.cpp
@@ -0,0 +1,139 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/cxfa_measurement.h"
+
+#include "xfa/fgas/crt/fgas_system.h"
+
+CXFA_Measurement::CXFA_Measurement(const CFX_WideStringC& wsMeasure) {
+  Set(wsMeasure);
+}
+
+CXFA_Measurement::CXFA_Measurement() {
+  Set(-1, XFA_UNIT_Unknown);
+}
+
+CXFA_Measurement::CXFA_Measurement(FX_FLOAT fValue, XFA_UNIT eUnit) {
+  Set(fValue, eUnit);
+}
+
+void CXFA_Measurement::Set(const CFX_WideStringC& wsMeasure) {
+  if (wsMeasure.IsEmpty()) {
+    m_fValue = 0;
+    m_eUnit = XFA_UNIT_Unknown;
+    return;
+  }
+  int32_t iUsedLen = 0;
+  int32_t iOffset = (wsMeasure.GetAt(0) == L'=') ? 1 : 0;
+  FX_FLOAT fValue = FX_wcstof(wsMeasure.c_str() + iOffset,
+                              wsMeasure.GetLength() - iOffset, &iUsedLen);
+  XFA_UNIT eUnit = GetUnit(wsMeasure.Mid(iOffset + iUsedLen));
+  Set(fValue, eUnit);
+}
+
+FX_BOOL CXFA_Measurement::ToString(CFX_WideString& wsMeasure) const {
+  switch (GetUnit()) {
+    case XFA_UNIT_Mm:
+      wsMeasure.Format(L"%.8gmm", GetValue());
+      return TRUE;
+    case XFA_UNIT_Pt:
+      wsMeasure.Format(L"%.8gpt", GetValue());
+      return TRUE;
+    case XFA_UNIT_In:
+      wsMeasure.Format(L"%.8gin", GetValue());
+      return TRUE;
+    case XFA_UNIT_Cm:
+      wsMeasure.Format(L"%.8gcm", GetValue());
+      return TRUE;
+    case XFA_UNIT_Mp:
+      wsMeasure.Format(L"%.8gmp", GetValue());
+      return TRUE;
+    case XFA_UNIT_Pc:
+      wsMeasure.Format(L"%.8gpc", GetValue());
+      return TRUE;
+    case XFA_UNIT_Em:
+      wsMeasure.Format(L"%.8gem", GetValue());
+      return TRUE;
+    case XFA_UNIT_Percent:
+      wsMeasure.Format(L"%.8g%%", GetValue());
+      return TRUE;
+    default:
+      wsMeasure.Format(L"%.8g", GetValue());
+      return FALSE;
+  }
+}
+
+FX_BOOL CXFA_Measurement::ToUnit(XFA_UNIT eUnit, FX_FLOAT& fValue) const {
+  fValue = GetValue();
+  XFA_UNIT eFrom = GetUnit();
+  if (eFrom == eUnit)
+    return TRUE;
+
+  switch (eFrom) {
+    case XFA_UNIT_Pt:
+      break;
+    case XFA_UNIT_Mm:
+      fValue *= 72 / 2.54f / 10;
+      break;
+    case XFA_UNIT_In:
+      fValue *= 72;
+      break;
+    case XFA_UNIT_Cm:
+      fValue *= 72 / 2.54f;
+      break;
+    case XFA_UNIT_Mp:
+      fValue *= 0.001f;
+      break;
+    case XFA_UNIT_Pc:
+      fValue *= 12.0f;
+      break;
+    default:
+      fValue = 0;
+      return FALSE;
+  }
+  switch (eUnit) {
+    case XFA_UNIT_Pt:
+      return TRUE;
+    case XFA_UNIT_Mm:
+      fValue /= 72 / 2.54f / 10;
+      return TRUE;
+    case XFA_UNIT_In:
+      fValue /= 72;
+      return TRUE;
+    case XFA_UNIT_Cm:
+      fValue /= 72 / 2.54f;
+      return TRUE;
+    case XFA_UNIT_Mp:
+      fValue /= 0.001f;
+      return TRUE;
+    case XFA_UNIT_Pc:
+      fValue /= 12.0f;
+      return TRUE;
+    default:
+      fValue = 0;
+      return FALSE;
+  }
+}
+
+XFA_UNIT CXFA_Measurement::GetUnit(const CFX_WideStringC& wsUnit) {
+  if (wsUnit == FX_WSTRC(L"mm"))
+    return XFA_UNIT_Mm;
+  if (wsUnit == FX_WSTRC(L"pt"))
+    return XFA_UNIT_Pt;
+  if (wsUnit == FX_WSTRC(L"in"))
+    return XFA_UNIT_In;
+  if (wsUnit == FX_WSTRC(L"cm"))
+    return XFA_UNIT_Cm;
+  if (wsUnit == FX_WSTRC(L"pc"))
+    return XFA_UNIT_Pc;
+  if (wsUnit == FX_WSTRC(L"mp"))
+    return XFA_UNIT_Mp;
+  if (wsUnit == FX_WSTRC(L"em"))
+    return XFA_UNIT_Em;
+  if (wsUnit == FX_WSTRC(L"%"))
+    return XFA_UNIT_Percent;
+  return XFA_UNIT_Unknown;
+}
diff --git a/xfa/fxfa/parser/cxfa_measurement.h b/xfa/fxfa/parser/cxfa_measurement.h
new file mode 100644
index 0000000..744cc2b
--- /dev/null
+++ b/xfa/fxfa/parser/cxfa_measurement.h
@@ -0,0 +1,42 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_CXFA_MEASUREMENT_H_
+#define XFA_FXFA_PARSER_CXFA_MEASUREMENT_H_
+
+#include "core/fxcrt/include/fx_string.h"
+#include "core/fxcrt/include/fx_system.h"
+#include "xfa/fxfa/include/fxfa_basic.h"
+
+class CXFA_Measurement {
+ public:
+  explicit CXFA_Measurement(const CFX_WideStringC& wsMeasure);
+  CXFA_Measurement();
+  CXFA_Measurement(FX_FLOAT fValue, XFA_UNIT eUnit);
+
+  void Set(const CFX_WideStringC& wsMeasure);
+  void Set(FX_FLOAT fValue, XFA_UNIT eUnit) {
+    m_fValue = fValue;
+    m_eUnit = eUnit;
+  }
+
+  XFA_UNIT GetUnit(const CFX_WideStringC& wsUnit);
+  XFA_UNIT GetUnit() const { return m_eUnit; }
+  FX_FLOAT GetValue() const { return m_fValue; }
+
+  FX_BOOL ToString(CFX_WideString& wsMeasure) const;
+  FX_BOOL ToUnit(XFA_UNIT eUnit, FX_FLOAT& fValue) const;
+  FX_FLOAT ToUnit(XFA_UNIT eUnit) const {
+    FX_FLOAT f;
+    return ToUnit(eUnit, f) ? f : 0;
+  }
+
+ private:
+  FX_FLOAT m_fValue;
+  XFA_UNIT m_eUnit;
+};
+
+#endif  // XFA_FXFA_PARSER_CXFA_MEASUREMENT_H_
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index 8f352d3..44b7e2f 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -17,6 +17,7 @@
 #include "xfa/fgas/crt/fgas_system.h"
 #include "xfa/fxfa/app/xfa_ffnotify.h"
 #include "xfa/fxfa/include/cxfa_eventparam.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
 #include "xfa/fxfa/parser/cxfa_occur.h"
 #include "xfa/fxfa/parser/cxfa_scriptcontext.h"
 #include "xfa/fxfa/parser/cxfa_simple_parser.h"
@@ -445,6 +446,28 @@
                             (eAttribute << 8) | XFA_KEYTYPE_Element);
 }
 
+const XFA_ATTRIBUTEINFO* GetAttributeOfElement(XFA_Element eElement,
+                                               XFA_ATTRIBUTE eAttribute,
+                                               uint32_t dwPacket) {
+  int32_t iCount = 0;
+  const uint8_t* pAttr = XFA_GetElementAttributes(eElement, iCount);
+  if (!pAttr || iCount < 1)
+    return nullptr;
+
+  if (!std::binary_search(pAttr, pAttr + iCount, eAttribute))
+    return nullptr;
+
+  const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttribute);
+  ASSERT(pInfo);
+  if (dwPacket == XFA_XDPPACKET_UNKNOWN)
+    return pInfo;
+  return (dwPacket & pInfo->dwPackets) ? pInfo : nullptr;
+}
+
+const XFA_ATTRIBUTEENUMINFO* GetAttributeEnumByID(XFA_ATTRIBUTEENUM eName) {
+  return g_XFAEnumData + eName;
+}
+
 }  // namespace
 
 static void XFA_DefaultFreeData(void* pData) {}
@@ -2335,7 +2358,7 @@
   } else {
     int32_t iValue = validate.GetNullTest();
     const XFA_ATTRIBUTEENUMINFO* pInfo =
-        XFA_GetAttributeEnumByID((XFA_ATTRIBUTEENUM)iValue);
+        GetAttributeEnumByID((XFA_ATTRIBUTEENUM)iValue);
     CFX_WideString wsValue;
     if (pInfo)
       wsValue = pInfo->pName;
@@ -2920,8 +2943,8 @@
       pArguments->GetReturnValue()->SetNull();
     } else {
       if (!strName.IsEmpty()) {
-        if (XFA_GetAttributeOfElement(eType, XFA_ATTRIBUTE_Name,
-                                      XFA_XDPPACKET_UNKNOWN)) {
+        if (GetAttributeOfElement(eType, XFA_ATTRIBUTE_Name,
+                                  XFA_XDPPACKET_UNKNOWN)) {
           pNewNode->SetAttribute(XFA_ATTRIBUTE_Name, strName.AsStringC(), true);
           if (pNewNode->GetPacketID() == XFA_XDPPACKET_Datasets) {
             pNewNode->CreateXMLMappingNode();
@@ -3709,7 +3732,7 @@
       if (!TryEnum(pAttr->eName, eValue, bUseDefault)) {
         return FALSE;
       }
-      wsValue = XFA_GetAttributeEnumByID(eValue)->pName;
+      wsValue = GetAttributeEnumByID(eValue)->pName;
       return TRUE;
     } break;
     case XFA_ATTRIBUTETYPE_Cdata: {
@@ -4058,7 +4081,7 @@
           static_cast<CFDE_XMLElement*>(m_pXMLNode)
               ->SetString(
                   pInfo->pName,
-                  XFA_GetAttributeEnumByID((XFA_ATTRIBUTEENUM)(uintptr_t)pValue)
+                  GetAttributeEnumByID((XFA_ATTRIBUTEENUM)(uintptr_t)pValue)
                       ->pName);
           break;
         case XFA_ATTRIBUTETYPE_Boolean:
@@ -4891,7 +4914,7 @@
     wsName = GetCData(XFA_ATTRIBUTE_Name);
     m_dwNameHash = FX_HashCode_GetW(wsName, false);
   } else if (pNotsure->eType == XFA_ATTRIBUTETYPE_Enum) {
-    wsName = XFA_GetAttributeEnumByID(GetEnum(XFA_ATTRIBUTE_Name))->pName;
+    wsName = GetAttributeEnumByID(GetEnum(XFA_ATTRIBUTE_Name))->pName;
     m_dwNameHash = FX_HashCode_GetW(wsName, false);
   }
 }
diff --git a/xfa/fxfa/parser/cxfa_para.cpp b/xfa/fxfa/parser/cxfa_para.cpp
index 4f4a169..bd3a1bb 100644
--- a/xfa/fxfa/parser/cxfa_para.cpp
+++ b/xfa/fxfa/parser/cxfa_para.cpp
@@ -6,6 +6,7 @@
 
 #include "xfa/fxfa/parser/cxfa_para.h"
 
+#include "xfa/fxfa/parser/cxfa_measurement.h"
 #include "xfa/fxfa/parser/xfa_object.h"
 
 CXFA_Para::CXFA_Para(CXFA_Node* pNode) : CXFA_Data(pNode) {}
diff --git a/xfa/fxfa/parser/cxfa_scriptcontext.cpp b/xfa/fxfa/parser/cxfa_scriptcontext.cpp
index 16c4696..f59700a 100644
--- a/xfa/fxfa/parser/cxfa_scriptcontext.cpp
+++ b/xfa/fxfa/parser/cxfa_scriptcontext.cpp
@@ -14,6 +14,7 @@
 #include "xfa/fxfa/include/cxfa_eventparam.h"
 #include "xfa/fxfa/parser/cxfa_nodehelper.h"
 #include "xfa/fxfa/parser/cxfa_resolveprocessor.h"
+#include "xfa/fxfa/parser/xfa_basic_data.h"
 #include "xfa/fxfa/parser/xfa_doclayout.h"
 #include "xfa/fxfa/parser/xfa_document.h"
 #include "xfa/fxfa/parser/xfa_localemgr.h"
@@ -71,6 +72,38 @@
   return static_cast<CXFA_ThisProxy*>(pValue->ToHostObject(pClass));
 }
 
+const XFA_METHODINFO* GetMethodByName(XFA_Element eElement,
+                                      const CFX_WideStringC& wsMethodName) {
+  if (wsMethodName.IsEmpty())
+    return nullptr;
+
+  int32_t iElementIndex = static_cast<int32_t>(eElement);
+  while (iElementIndex >= 0 && iElementIndex < g_iScriptIndexCount) {
+    const XFA_SCRIPTHIERARCHY* scriptIndex = g_XFAScriptIndex + iElementIndex;
+    int32_t icount = scriptIndex->wMethodCount;
+    if (icount == 0) {
+      iElementIndex = scriptIndex->wParentIndex;
+      continue;
+    }
+    uint32_t uHash = FX_HashCode_GetW(wsMethodName, false);
+    int32_t iStart = scriptIndex->wMethodStart;
+    // TODO(dsinclair): Switch to std::lower_bound.
+    int32_t iEnd = iStart + icount - 1;
+    do {
+      int32_t iMid = (iStart + iEnd) / 2;
+      const XFA_METHODINFO* pInfo = g_SomMethodData + iMid;
+      if (uHash == pInfo->uHash)
+        return pInfo;
+      if (uHash < pInfo->uHash)
+        iEnd = iMid - 1;
+      else
+        iStart = iMid + 1;
+    } while (iStart <= iEnd);
+    iElementIndex = scriptIndex->wParentIndex;
+  }
+  return nullptr;
+}
+
 }  // namespace
 
 // static.
@@ -357,7 +390,7 @@
   pObject = lpScriptContext->GetVariablesThis(pObject);
   XFA_Element eType = pObject->GetElementType();
   CFX_WideString wsPropName = CFX_WideString::FromUTF8(szPropName);
-  if (XFA_GetMethodByName(eType, wsPropName.AsStringC())) {
+  if (GetMethodByName(eType, wsPropName.AsStringC())) {
     return FXJSE_ClassPropType_Method;
   }
   if (bQueryIn &&
@@ -379,7 +412,7 @@
   pObject = lpScriptContext->GetVariablesThis(pObject);
   XFA_Element eType = pObject->GetElementType();
   CFX_WideString wsPropName = CFX_WideString::FromUTF8(szPropName);
-  if (XFA_GetMethodByName(eType, wsPropName.AsStringC())) {
+  if (GetMethodByName(eType, wsPropName.AsStringC())) {
     return FXJSE_ClassPropType_Method;
   }
   return FXJSE_ClassPropType_Property;
@@ -396,7 +429,7 @@
   pObject = lpScriptContext->GetVariablesThis(pObject);
   CFX_WideString wsFunName = CFX_WideString::FromUTF8(szFuncName);
   const XFA_METHODINFO* lpMethodInfo =
-      XFA_GetMethodByName(pObject->GetElementType(), wsFunName.AsStringC());
+      GetMethodByName(pObject->GetElementType(), wsFunName.AsStringC());
   if (!lpMethodInfo)
     return;
 
diff --git a/xfa/fxfa/parser/cxfa_simple_parser.cpp b/xfa/fxfa/parser/cxfa_simple_parser.cpp
index 7f70c81..043c56a 100644
--- a/xfa/fxfa/parser/cxfa_simple_parser.cpp
+++ b/xfa/fxfa/parser/cxfa_simple_parser.cpp
@@ -6,11 +6,15 @@
 
 #include "xfa/fxfa/parser/cxfa_simple_parser.h"
 
+#include "core/fxcrt/include/fx_ext.h"
 #include "xfa/fgas/crt/fgas_codepage.h"
 #include "xfa/fxfa/include/fxfa.h"
 #include "xfa/fxfa/include/xfa_checksum.h"
+#include "xfa/fxfa/parser/cxfa_widetextread.h"
 #include "xfa/fxfa/parser/cxfa_xml_parser.h"
+#include "xfa/fxfa/parser/xfa_basic_data.h"
 #include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
 
 namespace {
 
@@ -224,6 +228,26 @@
   }
 }
 
+const XFA_PACKETINFO* GetPacketByName(const CFX_WideStringC& wsName) {
+  if (wsName.IsEmpty())
+    return nullptr;
+
+  uint32_t uHash = FX_HashCode_GetW(wsName, false);
+  int32_t iStart = 0;
+  int32_t iEnd = g_iXFAPacketCount - 1;
+  do {
+    int32_t iMid = (iStart + iEnd) / 2;
+    const XFA_PACKETINFO* pInfo = g_XFAPacketData + iMid;
+    if (uHash == pInfo->uHash)
+      return pInfo;
+    if (uHash < pInfo->uHash)
+      iEnd = iMid - 1;
+    else
+      iStart = iMid + 1;
+  } while (iStart <= iEnd);
+  return nullptr;
+}
+
 }  // namespace
 
 FX_BOOL XFA_RecognizeRichText(CFDE_XMLElement* pRichTextXMLNode) {
@@ -301,10 +325,7 @@
   CloseParser();
   pXMLNode = nullptr;
 
-  std::unique_ptr<IFX_Stream> pStream(XFA_CreateWideTextRead(wsXML));
-  if (!pStream)
-    return XFA_PARSESTATUS_StreamErr;
-
+  std::unique_ptr<IFX_Stream> pStream(new CXFA_WideTextRead(wsXML));
   m_pXMLDoc.reset(new CFDE_XMLDoc);
   CXFA_XMLParser* pParser =
       new CXFA_XMLParser(m_pXMLDoc->GetRoot(), pStream.get());
@@ -504,7 +525,7 @@
       CFX_WideString wsPacketName;
       pElement->GetLocalTagName(wsPacketName);
       const XFA_PACKETINFO* pPacketInfo =
-          XFA_GetPacketByName(wsPacketName.AsStringC());
+          GetPacketByName(wsPacketName.AsStringC());
       if (pPacketInfo && pPacketInfo->pURI) {
         if (!MatchNodeName(pElement, pPacketInfo->pName, pPacketInfo->pURI,
                            pPacketInfo->eFlags)) {
diff --git a/xfa/fxfa/parser/cxfa_stroke.cpp b/xfa/fxfa/parser/cxfa_stroke.cpp
index 0733f3a..77549f0 100644
--- a/xfa/fxfa/parser/cxfa_stroke.cpp
+++ b/xfa/fxfa/parser/cxfa_stroke.cpp
@@ -6,6 +6,7 @@
 
 #include "xfa/fxfa/parser/cxfa_stroke.h"
 
+#include "xfa/fxfa/parser/cxfa_measurement.h"
 #include "xfa/fxfa/parser/xfa_object.h"
 
 int32_t CXFA_Stroke::GetPresence() const {
diff --git a/xfa/fxfa/parser/cxfa_widetextread.cpp b/xfa/fxfa/parser/cxfa_widetextread.cpp
new file mode 100644
index 0000000..90abe9a
--- /dev/null
+++ b/xfa/fxfa/parser/cxfa_widetextread.cpp
@@ -0,0 +1,107 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/cxfa_widetextread.h"
+
+#include "core/fxcrt/include/fx_ext.h"
+#include "xfa/fgas/crt/fgas_codepage.h"
+
+CXFA_WideTextRead::CXFA_WideTextRead(const CFX_WideString& wsBuffer)
+    : m_wsBuffer(wsBuffer), m_iPosition(0), m_iRefCount(1) {}
+
+void CXFA_WideTextRead::Release() {
+  if (--m_iRefCount < 1)
+    delete this;
+}
+
+IFX_Stream* CXFA_WideTextRead::Retain() {
+  m_iRefCount++;
+  return this;
+}
+
+uint32_t CXFA_WideTextRead::GetAccessModes() const {
+  return FX_STREAMACCESS_Read | FX_STREAMACCESS_Text;
+}
+
+int32_t CXFA_WideTextRead::GetLength() const {
+  return m_wsBuffer.GetLength() * sizeof(FX_WCHAR);
+}
+
+int32_t CXFA_WideTextRead::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
+  switch (eSeek) {
+    case FX_STREAMSEEK_Begin:
+      m_iPosition = iOffset;
+      break;
+    case FX_STREAMSEEK_Current:
+      m_iPosition += iOffset;
+      break;
+    case FX_STREAMSEEK_End:
+      m_iPosition = m_wsBuffer.GetLength() + iOffset;
+      break;
+  }
+  m_iPosition = std::min(std::max(0, m_iPosition), m_wsBuffer.GetLength());
+  return GetPosition();
+}
+
+int32_t CXFA_WideTextRead::GetPosition() {
+  return m_iPosition * sizeof(FX_WCHAR);
+}
+
+FX_BOOL CXFA_WideTextRead::IsEOF() const {
+  return m_iPosition >= m_wsBuffer.GetLength();
+}
+
+int32_t CXFA_WideTextRead::ReadData(uint8_t* pBuffer, int32_t iBufferSize) {
+  return 0;
+}
+
+int32_t CXFA_WideTextRead::ReadString(FX_WCHAR* pStr,
+                                      int32_t iMaxLength,
+                                      FX_BOOL& bEOS) {
+  iMaxLength = std::min(iMaxLength, m_wsBuffer.GetLength() - m_iPosition);
+  if (iMaxLength == 0)
+    return 0;
+
+  FXSYS_wcsncpy(pStr, m_wsBuffer.c_str() + m_iPosition, iMaxLength);
+  m_iPosition += iMaxLength;
+  bEOS = IsEOF();
+  return iMaxLength;
+}
+
+int32_t CXFA_WideTextRead::WriteData(const uint8_t* pBuffer,
+                                     int32_t iBufferSize) {
+  return 0;
+}
+
+int32_t CXFA_WideTextRead::WriteString(const FX_WCHAR* pStr, int32_t iLength) {
+  return 0;
+}
+
+FX_BOOL CXFA_WideTextRead::SetLength(int32_t iLength) {
+  return FALSE;
+}
+
+int32_t CXFA_WideTextRead::GetBOM(uint8_t bom[4]) const {
+  return 0;
+}
+
+uint16_t CXFA_WideTextRead::GetCodePage() const {
+  return (sizeof(FX_WCHAR) == 2) ? FX_CODEPAGE_UTF16LE : FX_CODEPAGE_UTF32LE;
+}
+
+uint16_t CXFA_WideTextRead::SetCodePage(uint16_t wCodePage) {
+  return GetCodePage();
+}
+
+IFX_Stream* CXFA_WideTextRead::CreateSharedStream(uint32_t dwAccess,
+                                                  int32_t iOffset,
+                                                  int32_t iLength) {
+  return nullptr;
+}
+
+CFX_WideString CXFA_WideTextRead::GetSrcText() const {
+  return m_wsBuffer;
+}
diff --git a/xfa/fxfa/parser/xfa_basic_imp.h b/xfa/fxfa/parser/cxfa_widetextread.h
similarity index 72%
rename from xfa/fxfa/parser/xfa_basic_imp.h
rename to xfa/fxfa/parser/cxfa_widetextread.h
index 8ca153b..9ee2c41 100644
--- a/xfa/fxfa/parser/xfa_basic_imp.h
+++ b/xfa/fxfa/parser/cxfa_widetextread.h
@@ -1,25 +1,13 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2016 PDFium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#ifndef XFA_FXFA_PARSER_XFA_BASIC_IMP_H_
-#define XFA_FXFA_PARSER_XFA_BASIC_IMP_H_
+#ifndef XFA_FXFA_PARSER_CXFA_WIDETEXTREAD_H_
+#define XFA_FXFA_PARSER_CXFA_WIDETEXTREAD_H_
 
 #include "xfa/fgas/crt/fgas_stream.h"
-#include "xfa/fxfa/include/fxfa_basic.h"
-
-struct XFA_NOTSUREATTRIBUTE {
-  XFA_Element eElement;
-  XFA_ATTRIBUTE eAttribute;
-  XFA_ATTRIBUTETYPE eType;
-  void* pValue;
-};
-const XFA_NOTSUREATTRIBUTE* XFA_GetNotsureAttribute(
-    XFA_Element eElement,
-    XFA_ATTRIBUTE eAttribute,
-    XFA_ATTRIBUTETYPE eType = XFA_ATTRIBUTETYPE_NOTSURE);
 
 class CXFA_WideTextRead : public IFX_Stream {
  public:
@@ -48,9 +36,6 @@
                                  int32_t iOffset,
                                  int32_t iLength) override;
 
-  virtual void Lock();
-  virtual void Unlock();
-
   CFX_WideString GetSrcText() const;
 
  protected:
@@ -59,4 +44,4 @@
   int32_t m_iRefCount;
 };
 
-#endif  // XFA_FXFA_PARSER_XFA_BASIC_IMP_H_
+#endif  // XFA_FXFA_PARSER_CXFA_WIDETEXTREAD_H_
diff --git a/xfa/fxfa/parser/cxfa_widgetdata.cpp b/xfa/fxfa/parser/cxfa_widgetdata.cpp
index f372c51..ae3fece 100644
--- a/xfa/fxfa/parser/cxfa_widgetdata.cpp
+++ b/xfa/fxfa/parser/cxfa_widgetdata.cpp
@@ -10,6 +10,7 @@
 #include "xfa/fxbarcode/include/BC_Library.h"
 #include "xfa/fxfa/app/xfa_ffnotify.h"
 #include "xfa/fxfa/parser/cxfa_event.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
 #include "xfa/fxfa/parser/xfa_document.h"
 #include "xfa/fxfa/parser/xfa_localevalue.h"
 #include "xfa/fxfa/parser/xfa_object.h"
@@ -206,6 +207,39 @@
   return pUIChild;
 }
 
+XFA_ATTRIBUTEENUM GetAttributeDefaultValue_Enum(XFA_Element eElement,
+                                                XFA_ATTRIBUTE eAttribute,
+                                                uint32_t dwPacket) {
+  void* pValue;
+  if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
+                                   XFA_ATTRIBUTETYPE_Enum, dwPacket)) {
+    return (XFA_ATTRIBUTEENUM)(uintptr_t)pValue;
+  }
+  return XFA_ATTRIBUTEENUM_Unknown;
+}
+
+CFX_WideStringC GetAttributeDefaultValue_Cdata(XFA_Element eElement,
+                                               XFA_ATTRIBUTE eAttribute,
+                                               uint32_t dwPacket) {
+  void* pValue;
+  if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
+                                   XFA_ATTRIBUTETYPE_Cdata, dwPacket)) {
+    return (const FX_WCHAR*)pValue;
+  }
+  return nullptr;
+}
+
+FX_BOOL GetAttributeDefaultValue_Boolean(XFA_Element eElement,
+                                         XFA_ATTRIBUTE eAttribute,
+                                         uint32_t dwPacket) {
+  void* pValue;
+  if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
+                                   XFA_ATTRIBUTETYPE_Boolean, dwPacket)) {
+    return (FX_BOOL)(uintptr_t)pValue;
+  }
+  return FALSE;
+}
+
 }  // namespace
 
 CXFA_WidgetData::CXFA_WidgetData(CXFA_Node* pNode)
@@ -417,7 +451,7 @@
   CXFA_Node* pUIChild = GetUIChild();
   if (pUIChild)
     return pUIChild->GetEnum(XFA_ATTRIBUTE_Highlight);
-  return XFA_GetAttributeDefaultValue_Enum(
+  return GetAttributeDefaultValue_Enum(
       XFA_Element::Button, XFA_ATTRIBUTE_Highlight, XFA_XDPPACKET_Form);
 }
 
@@ -461,16 +495,16 @@
   CXFA_Node* pUIChild = GetUIChild();
   if (pUIChild)
     return pUIChild->GetEnum(XFA_ATTRIBUTE_Shape);
-  return XFA_GetAttributeDefaultValue_Enum(
-      XFA_Element::CheckButton, XFA_ATTRIBUTE_Shape, XFA_XDPPACKET_Form);
+  return GetAttributeDefaultValue_Enum(XFA_Element::CheckButton,
+                                       XFA_ATTRIBUTE_Shape, XFA_XDPPACKET_Form);
 }
 
 int32_t CXFA_WidgetData::GetCheckButtonMark() {
   CXFA_Node* pUIChild = GetUIChild();
   if (pUIChild)
     return pUIChild->GetEnum(XFA_ATTRIBUTE_Mark);
-  return XFA_GetAttributeDefaultValue_Enum(
-      XFA_Element::CheckButton, XFA_ATTRIBUTE_Mark, XFA_XDPPACKET_Form);
+  return GetAttributeDefaultValue_Enum(XFA_Element::CheckButton,
+                                       XFA_ATTRIBUTE_Mark, XFA_XDPPACKET_Form);
 }
 
 FX_BOOL CXFA_WidgetData::IsRadioButton() {
@@ -492,7 +526,7 @@
   CXFA_Node* pUIChild = GetUIChild();
   if (pUIChild)
     return pUIChild->GetBoolean(XFA_ATTRIBUTE_AllowNeutral);
-  return XFA_GetAttributeDefaultValue_Boolean(
+  return GetAttributeDefaultValue_Boolean(
       XFA_Element::CheckButton, XFA_ATTRIBUTE_AllowNeutral, XFA_XDPPACKET_Form);
 }
 
@@ -681,7 +715,7 @@
   CXFA_Node* pUIChild = GetUIChild();
   if (pUIChild)
     return pUIChild->GetEnum(XFA_ATTRIBUTE_CommitOn);
-  return XFA_GetAttributeDefaultValue_Enum(
+  return GetAttributeDefaultValue_Enum(
       XFA_Element::ChoiceList, XFA_ATTRIBUTE_CommitOn, XFA_XDPPACKET_Form);
 }
 
@@ -689,7 +723,7 @@
   CXFA_Node* pUIChild = GetUIChild();
   if (pUIChild)
     return pUIChild->GetBoolean(XFA_ATTRIBUTE_TextEntry);
-  return XFA_GetAttributeDefaultValue_Boolean(
+  return GetAttributeDefaultValue_Boolean(
       XFA_Element::ChoiceList, XFA_ATTRIBUTE_TextEntry, XFA_XDPPACKET_Form);
 }
 
@@ -697,8 +731,8 @@
   CXFA_Node* pUIChild = GetUIChild();
   if (pUIChild)
     return pUIChild->GetEnum(XFA_ATTRIBUTE_Open);
-  return XFA_GetAttributeDefaultValue_Enum(
-      XFA_Element::ChoiceList, XFA_ATTRIBUTE_Open, XFA_XDPPACKET_Form);
+  return GetAttributeDefaultValue_Enum(XFA_Element::ChoiceList,
+                                       XFA_ATTRIBUTE_Open, XFA_XDPPACKET_Form);
 }
 
 FX_BOOL CXFA_WidgetData::IsListBox() {
@@ -1387,9 +1421,9 @@
   if (pUIChild) {
     pUIChild->TryCData(XFA_ATTRIBUTE_PasswordChar, wsPassWord);
   } else {
-    wsPassWord = XFA_GetAttributeDefaultValue_Cdata(XFA_Element::PasswordEdit,
-                                                    XFA_ATTRIBUTE_PasswordChar,
-                                                    XFA_XDPPACKET_Form);
+    wsPassWord = GetAttributeDefaultValue_Cdata(XFA_Element::PasswordEdit,
+                                                XFA_ATTRIBUTE_PasswordChar,
+                                                XFA_XDPPACKET_Form);
   }
 }
 
@@ -1397,7 +1431,7 @@
   CXFA_Node* pUIChild = GetUIChild();
   if (pUIChild)
     return pUIChild->GetBoolean(XFA_ATTRIBUTE_MultiLine);
-  return XFA_GetAttributeDefaultValue_Boolean(
+  return GetAttributeDefaultValue_Boolean(
       XFA_Element::TextEdit, XFA_ATTRIBUTE_MultiLine, XFA_XDPPACKET_Form);
 }
 
@@ -1405,7 +1439,7 @@
   CXFA_Node* pUIChild = GetUIChild();
   if (pUIChild)
     return pUIChild->GetEnum(XFA_ATTRIBUTE_VScrollPolicy);
-  return XFA_GetAttributeDefaultValue_Enum(
+  return GetAttributeDefaultValue_Enum(
       XFA_Element::TextEdit, XFA_ATTRIBUTE_VScrollPolicy, XFA_XDPPACKET_Form);
 }
 
diff --git a/xfa/fxfa/parser/xfa_basic_data.h b/xfa/fxfa/parser/xfa_basic_data.h
index b3f67dc..119ef85 100644
--- a/xfa/fxfa/parser/xfa_basic_data.h
+++ b/xfa/fxfa/parser/xfa_basic_data.h
@@ -8,7 +8,6 @@
 #define XFA_FXFA_PARSER_XFA_BASIC_DATA_H_
 
 #include "xfa/fxfa/include/fxfa_basic.h"
-#include "xfa/fxfa/parser/xfa_basic_imp.h"
 
 extern const XFA_PACKETINFO g_XFAPacketData[];
 extern const int32_t g_iXFAPacketCount;
@@ -35,6 +34,7 @@
 extern const XFA_PROPERTY g_XFAElementPropertyData[];
 
 extern const XFA_SCRIPTHIERARCHY g_XFAScriptIndex[];
+extern const int32_t g_iScriptIndexCount;
 
 extern const XFA_NOTSUREATTRIBUTE g_XFANotsureAttributes[];
 extern const int32_t g_iXFANotsureCount;
diff --git a/xfa/fxfa/parser/xfa_basic_data_attributes.cpp b/xfa/fxfa/parser/xfa_basic_data_attributes.cpp
index 09fe7ce..66d4be2 100644
--- a/xfa/fxfa/parser/xfa_basic_data_attributes.cpp
+++ b/xfa/fxfa/parser/xfa_basic_data_attributes.cpp
@@ -7,6 +7,7 @@
 #include "xfa/fxfa/parser/xfa_basic_data.h"
 
 #include "xfa/fxfa/include/fxfa_basic.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
 
 static const CXFA_Measurement g_XFAMeasurementData[] = {
     CXFA_Measurement(0, XFA_UNIT_In),
diff --git a/xfa/fxfa/parser/xfa_basic_data_element_script.cpp b/xfa/fxfa/parser/xfa_basic_data_element_script.cpp
index f4be53b..c4b3818 100644
--- a/xfa/fxfa/parser/xfa_basic_data_element_script.cpp
+++ b/xfa/fxfa/parser/xfa_basic_data_element_script.cpp
@@ -123,6 +123,8 @@
     {120, 2, 1057, 8, 312}, {122, 11, 1065, 6, 315}, {133, 2, 1071, 0, 316},
     {135, 0, 1071, 0, 316}, {135, 3, 1071, 2, 316},  {138, 0, 1073, 2, 316},
 };
+const int32_t g_iScriptIndexCount =
+    sizeof(g_XFAScriptIndex) / sizeof(XFA_SCRIPTHIERARCHY);
 
 const XFA_METHODINFO g_SomMethodData[] = {
     {0x3c752495, L"verify",
diff --git a/xfa/fxfa/parser/xfa_basic_imp.cpp b/xfa/fxfa/parser/xfa_basic_imp.cpp
deleted file mode 100644
index 4632860..0000000
--- a/xfa/fxfa/parser/xfa_basic_imp.cpp
+++ /dev/null
@@ -1,588 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "xfa/fxfa/parser/xfa_basic_imp.h"
-
-#include "core/fxcrt/include/fx_ext.h"
-#include "xfa/fgas/crt/fgas_codepage.h"
-#include "xfa/fgas/crt/fgas_system.h"
-#include "xfa/fxfa/parser/xfa_basic_data.h"
-#include "xfa/fxfa/parser/xfa_doclayout.h"
-#include "xfa/fxfa/parser/xfa_document.h"
-#include "xfa/fxfa/parser/xfa_localemgr.h"
-#include "xfa/fxfa/parser/xfa_object.h"
-#include "xfa/fxfa/parser/xfa_utils.h"
-
-const XFA_PACKETINFO* XFA_GetPacketByName(const CFX_WideStringC& wsName) {
-  if (wsName.IsEmpty())
-    return nullptr;
-
-  uint32_t uHash = FX_HashCode_GetW(wsName, false);
-  int32_t iStart = 0;
-  int32_t iEnd = g_iXFAPacketCount - 1;
-  do {
-    int32_t iMid = (iStart + iEnd) / 2;
-    const XFA_PACKETINFO* pInfo = g_XFAPacketData + iMid;
-    if (uHash == pInfo->uHash) {
-      return pInfo;
-    } else if (uHash < pInfo->uHash) {
-      iEnd = iMid - 1;
-    } else {
-      iStart = iMid + 1;
-    }
-  } while (iStart <= iEnd);
-  return nullptr;
-}
-
-const XFA_PACKETINFO* XFA_GetPacketByID(uint32_t dwPacket) {
-  int32_t iStart = 0, iEnd = g_iXFAPacketCount - 1;
-  do {
-    int32_t iMid = (iStart + iEnd) / 2;
-    uint32_t dwFind = (g_XFAPacketData + iMid)->eName;
-    if (dwPacket == dwFind) {
-      return g_XFAPacketData + iMid;
-    } else if (dwPacket < dwFind) {
-      iEnd = iMid - 1;
-    } else {
-      iStart = iMid + 1;
-    }
-  } while (iStart <= iEnd);
-  return nullptr;
-}
-
-const XFA_PACKETINFO* XFA_GetPacketByIndex(XFA_PACKET ePacket) {
-  return g_XFAPacketData + ePacket;
-}
-
-const XFA_ATTRIBUTEENUMINFO* XFA_GetAttributeEnumByName(
-    const CFX_WideStringC& wsName) {
-  if (wsName.IsEmpty())
-    return nullptr;
-
-  uint32_t uHash = FX_HashCode_GetW(wsName, false);
-  int32_t iStart = 0;
-  int32_t iEnd = g_iXFAEnumCount - 1;
-  do {
-    int32_t iMid = (iStart + iEnd) / 2;
-    const XFA_ATTRIBUTEENUMINFO* pInfo = g_XFAEnumData + iMid;
-    if (uHash == pInfo->uHash) {
-      return pInfo;
-    } else if (uHash < pInfo->uHash) {
-      iEnd = iMid - 1;
-    } else {
-      iStart = iMid + 1;
-    }
-  } while (iStart <= iEnd);
-  return nullptr;
-}
-const XFA_ATTRIBUTEENUMINFO* XFA_GetAttributeEnumByID(XFA_ATTRIBUTEENUM eName) {
-  return g_XFAEnumData + eName;
-}
-
-const XFA_ATTRIBUTEINFO* XFA_GetAttributeByName(const CFX_WideStringC& wsName) {
-  if (wsName.IsEmpty())
-    return nullptr;
-
-  uint32_t uHash = FX_HashCode_GetW(wsName, false);
-  int32_t iStart = 0;
-  int32_t iEnd = g_iXFAAttributeCount - 1;
-  do {
-    int32_t iMid = (iStart + iEnd) / 2;
-    const XFA_ATTRIBUTEINFO* pInfo = g_XFAAttributeData + iMid;
-    if (uHash == pInfo->uHash) {
-      return pInfo;
-    } else if (uHash < pInfo->uHash) {
-      iEnd = iMid - 1;
-    } else {
-      iStart = iMid + 1;
-    }
-  } while (iStart <= iEnd);
-  return nullptr;
-}
-const XFA_ATTRIBUTEINFO* XFA_GetAttributeByID(XFA_ATTRIBUTE eName) {
-  return (eName < g_iXFAAttributeCount) ? (g_XFAAttributeData + eName)
-                                        : nullptr;
-}
-FX_BOOL XFA_GetAttributeDefaultValue(void*& pValue,
-                                     XFA_Element eElement,
-                                     XFA_ATTRIBUTE eAttribute,
-                                     XFA_ATTRIBUTETYPE eType,
-                                     uint32_t dwPacket) {
-  const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttribute);
-  if (!pInfo) {
-    return FALSE;
-  }
-  if (dwPacket && (dwPacket & pInfo->dwPackets) == 0) {
-    return FALSE;
-  }
-  if (pInfo->eType == eType) {
-    pValue = pInfo->pDefValue;
-    return TRUE;
-  } else if (pInfo->eType == XFA_ATTRIBUTETYPE_NOTSURE) {
-    const XFA_NOTSUREATTRIBUTE* pAttr =
-        XFA_GetNotsureAttribute(eElement, eAttribute, eType);
-    if (pAttr) {
-      pValue = pAttr->pValue;
-      return TRUE;
-    }
-  }
-  return FALSE;
-}
-XFA_ATTRIBUTEENUM XFA_GetAttributeDefaultValue_Enum(XFA_Element eElement,
-                                                    XFA_ATTRIBUTE eAttribute,
-                                                    uint32_t dwPacket) {
-  void* pValue;
-  if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
-                                   XFA_ATTRIBUTETYPE_Enum, dwPacket)) {
-    return (XFA_ATTRIBUTEENUM)(uintptr_t)pValue;
-  }
-  return XFA_ATTRIBUTEENUM_Unknown;
-}
-CFX_WideStringC XFA_GetAttributeDefaultValue_Cdata(XFA_Element eElement,
-                                                   XFA_ATTRIBUTE eAttribute,
-                                                   uint32_t dwPacket) {
-  void* pValue;
-  if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
-                                   XFA_ATTRIBUTETYPE_Cdata, dwPacket)) {
-    return (const FX_WCHAR*)pValue;
-  }
-  return nullptr;
-}
-FX_BOOL XFA_GetAttributeDefaultValue_Boolean(XFA_Element eElement,
-                                             XFA_ATTRIBUTE eAttribute,
-                                             uint32_t dwPacket) {
-  void* pValue;
-  if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
-                                   XFA_ATTRIBUTETYPE_Boolean, dwPacket)) {
-    return (FX_BOOL)(uintptr_t)pValue;
-  }
-  return FALSE;
-}
-
-CXFA_Measurement XFA_GetAttributeDefaultValue_Measure(XFA_Element eElement,
-                                                      XFA_ATTRIBUTE eAttribute,
-                                                      uint32_t dwPacket) {
-  void* pValue;
-  if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
-                                   XFA_ATTRIBUTETYPE_Measure, dwPacket)) {
-    return *(CXFA_Measurement*)pValue;
-  }
-  return CXFA_Measurement();
-}
-
-XFA_Element XFA_GetElementTypeForName(const CFX_WideStringC& wsName) {
-  if (wsName.IsEmpty())
-    return XFA_Element::Unknown;
-
-  uint32_t uHash = FX_HashCode_GetW(wsName, false);
-  const XFA_ELEMENTINFO* pEnd = g_XFAElementData + g_iXFAElementCount;
-  auto pInfo = std::lower_bound(g_XFAElementData, pEnd, uHash,
-                                [](const XFA_ELEMENTINFO& info, uint32_t hash) {
-                                  return info.uHash < hash;
-                                });
-  if (pInfo < pEnd && pInfo->uHash == uHash)
-    return pInfo->eName;
-  return XFA_Element::Unknown;
-}
-
-const XFA_ELEMENTINFO* XFA_GetElementByID(XFA_Element eName) {
-  return eName == XFA_Element::Unknown
-             ? nullptr
-             : g_XFAElementData + static_cast<int32_t>(eName);
-}
-
-const uint8_t* XFA_GetElementAttributes(XFA_Element eElement, int32_t& iCount) {
-  if (eElement == XFA_Element::Unknown)
-    return nullptr;
-
-  const XFA_ELEMENTHIERARCHY* pElement =
-      g_XFAElementAttributeIndex + static_cast<int32_t>(eElement);
-  iCount = pElement->wCount;
-  return g_XFAElementAttributeData + pElement->wStart;
-}
-
-const XFA_ATTRIBUTEINFO* XFA_GetAttributeOfElement(XFA_Element eElement,
-                                                   XFA_ATTRIBUTE eAttribute,
-                                                   uint32_t dwPacket) {
-  int32_t iCount = 0;
-  const uint8_t* pAttr = XFA_GetElementAttributes(eElement, iCount);
-  if (!pAttr || iCount < 1)
-    return nullptr;
-
-  if (!std::binary_search(pAttr, pAttr + iCount, eAttribute))
-    return nullptr;
-
-  const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttribute);
-  ASSERT(pInfo);
-  if (dwPacket == XFA_XDPPACKET_UNKNOWN)
-    return pInfo;
-  return (dwPacket & pInfo->dwPackets) ? pInfo : nullptr;
-}
-
-const XFA_PROPERTY* XFA_GetElementProperties(XFA_Element eElement,
-                                             int32_t& iCount) {
-  if (eElement == XFA_Element::Unknown)
-    return nullptr;
-
-  const XFA_ELEMENTHIERARCHY* pElement =
-      g_XFAElementPropertyIndex + static_cast<int32_t>(eElement);
-  iCount = pElement->wCount;
-  return g_XFAElementPropertyData + pElement->wStart;
-}
-
-const XFA_PROPERTY* XFA_GetPropertyOfElement(XFA_Element eElement,
-                                             XFA_Element eProperty,
-                                             uint32_t dwPacket) {
-  int32_t iCount = 0;
-  const XFA_PROPERTY* pProperties = XFA_GetElementProperties(eElement, iCount);
-  if (!pProperties || iCount < 1)
-    return nullptr;
-
-  auto it = std::find_if(pProperties, pProperties + iCount,
-                         [eProperty](const XFA_PROPERTY& prop) {
-                           return prop.eName == eProperty;
-                         });
-  if (it == pProperties + iCount)
-    return nullptr;
-
-  const XFA_ELEMENTINFO* pInfo = XFA_GetElementByID(eProperty);
-  ASSERT(pInfo);
-  if (dwPacket != XFA_XDPPACKET_UNKNOWN && !(dwPacket & pInfo->dwPackets))
-    return nullptr;
-  return it;
-}
-
-const XFA_NOTSUREATTRIBUTE* XFA_GetNotsureAttribute(XFA_Element eElement,
-                                                    XFA_ATTRIBUTE eAttribute,
-                                                    XFA_ATTRIBUTETYPE eType) {
-  int32_t iStart = 0, iEnd = g_iXFANotsureCount - 1;
-  do {
-    int32_t iMid = (iStart + iEnd) / 2;
-    const XFA_NOTSUREATTRIBUTE* pAttr = g_XFANotsureAttributes + iMid;
-    if (eElement == pAttr->eElement) {
-      if (pAttr->eAttribute == eAttribute) {
-        if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType) {
-          return pAttr;
-        }
-        return nullptr;
-      } else {
-        int32_t iBefore = iMid - 1;
-        if (iBefore >= 0) {
-          pAttr = g_XFANotsureAttributes + iBefore;
-          while (eElement == pAttr->eElement) {
-            if (pAttr->eAttribute == eAttribute) {
-              if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType) {
-                return pAttr;
-              }
-              return nullptr;
-            }
-            iBefore--;
-            if (iBefore < 0) {
-              break;
-            }
-            pAttr = g_XFANotsureAttributes + iBefore;
-          }
-        }
-        int32_t iAfter = iMid + 1;
-        if (iAfter <= g_iXFANotsureCount - 1) {
-          pAttr = g_XFANotsureAttributes + iAfter;
-          while (eElement == pAttr->eElement) {
-            if (pAttr->eAttribute == eAttribute) {
-              if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType) {
-                return pAttr;
-              }
-              return nullptr;
-            }
-            iAfter++;
-            if (iAfter > g_iXFANotsureCount - 1) {
-              break;
-            }
-            pAttr = g_XFANotsureAttributes + iAfter;
-          }
-        }
-        return nullptr;
-      }
-    } else if (eElement < pAttr->eElement) {
-      iEnd = iMid - 1;
-    } else {
-      iStart = iMid + 1;
-    }
-  } while (iStart <= iEnd);
-  return nullptr;
-}
-
-const XFA_METHODINFO* XFA_GetMethodByName(XFA_Element eElement,
-                                          const CFX_WideStringC& wsMethodName) {
-  if (wsMethodName.IsEmpty())
-    return nullptr;
-
-  int32_t iElementIndex = static_cast<int32_t>(eElement);
-  while (iElementIndex != -1) {
-    const XFA_SCRIPTHIERARCHY* scriptIndex = g_XFAScriptIndex + iElementIndex;
-    int32_t icount = scriptIndex->wMethodCount;
-    if (icount == 0) {
-      iElementIndex = scriptIndex->wParentIndex;
-      continue;
-    }
-    uint32_t uHash = FX_HashCode_GetW(wsMethodName, false);
-    int32_t iStart = scriptIndex->wMethodStart;
-    int32_t iEnd = iStart + icount - 1;
-    do {
-      int32_t iMid = (iStart + iEnd) / 2;
-      const XFA_METHODINFO* pInfo = g_SomMethodData + iMid;
-      if (uHash == pInfo->uHash) {
-        return pInfo;
-      } else if (uHash < pInfo->uHash) {
-        iEnd = iMid - 1;
-      } else {
-        iStart = iMid + 1;
-      }
-    } while (iStart <= iEnd);
-    iElementIndex = scriptIndex->wParentIndex;
-  }
-  return nullptr;
-}
-const XFA_SCRIPTATTRIBUTEINFO* XFA_GetScriptAttributeByName(
-    XFA_Element eElement,
-    const CFX_WideStringC& wsAttributeName) {
-  if (wsAttributeName.IsEmpty())
-    return nullptr;
-
-  int32_t iElementIndex = static_cast<int32_t>(eElement);
-  while (iElementIndex != -1) {
-    const XFA_SCRIPTHIERARCHY* scriptIndex = g_XFAScriptIndex + iElementIndex;
-    int32_t icount = scriptIndex->wAttributeCount;
-    if (icount == 0) {
-      iElementIndex = scriptIndex->wParentIndex;
-      continue;
-    }
-    uint32_t uHash = FX_HashCode_GetW(wsAttributeName, false);
-    int32_t iStart = scriptIndex->wAttributeStart, iEnd = iStart + icount - 1;
-    do {
-      int32_t iMid = (iStart + iEnd) / 2;
-      const XFA_SCRIPTATTRIBUTEINFO* pInfo = g_SomAttributeData + iMid;
-      if (uHash == pInfo->uHash) {
-        return pInfo;
-      } else if (uHash < pInfo->uHash) {
-        iEnd = iMid - 1;
-      } else {
-        iStart = iMid + 1;
-      }
-    } while (iStart <= iEnd);
-    iElementIndex = scriptIndex->wParentIndex;
-  }
-  return nullptr;
-}
-void CXFA_Measurement::Set(const CFX_WideStringC& wsMeasure) {
-  if (wsMeasure.IsEmpty()) {
-    m_fValue = 0;
-    m_eUnit = XFA_UNIT_Unknown;
-    return;
-  }
-  int32_t iUsedLen = 0;
-  int32_t iOffset = (wsMeasure.GetAt(0) == L'=') ? 1 : 0;
-  FX_FLOAT fValue = FX_wcstof(wsMeasure.c_str() + iOffset,
-                              wsMeasure.GetLength() - iOffset, &iUsedLen);
-  XFA_UNIT eUnit = GetUnit(wsMeasure.Mid(iOffset + iUsedLen));
-  Set(fValue, eUnit);
-}
-FX_BOOL CXFA_Measurement::ToString(CFX_WideString& wsMeasure) const {
-  switch (GetUnit()) {
-    case XFA_UNIT_Mm:
-      wsMeasure.Format(L"%.8gmm", GetValue());
-      return TRUE;
-    case XFA_UNIT_Pt:
-      wsMeasure.Format(L"%.8gpt", GetValue());
-      return TRUE;
-    case XFA_UNIT_In:
-      wsMeasure.Format(L"%.8gin", GetValue());
-      return TRUE;
-    case XFA_UNIT_Cm:
-      wsMeasure.Format(L"%.8gcm", GetValue());
-      return TRUE;
-    case XFA_UNIT_Mp:
-      wsMeasure.Format(L"%.8gmp", GetValue());
-      return TRUE;
-    case XFA_UNIT_Pc:
-      wsMeasure.Format(L"%.8gpc", GetValue());
-      return TRUE;
-    case XFA_UNIT_Em:
-      wsMeasure.Format(L"%.8gem", GetValue());
-      return TRUE;
-    case XFA_UNIT_Percent:
-      wsMeasure.Format(L"%.8g%%", GetValue());
-      return TRUE;
-    default:
-      wsMeasure.Format(L"%.8g", GetValue());
-      return FALSE;
-  }
-}
-FX_BOOL CXFA_Measurement::ToUnit(XFA_UNIT eUnit, FX_FLOAT& fValue) const {
-  fValue = GetValue();
-  XFA_UNIT eFrom = GetUnit();
-  if (eFrom == eUnit) {
-    return TRUE;
-  }
-  switch (eFrom) {
-    case XFA_UNIT_Pt:
-      break;
-    case XFA_UNIT_Mm:
-      fValue *= 72 / 2.54f / 10;
-      break;
-    case XFA_UNIT_In:
-      fValue *= 72;
-      break;
-    case XFA_UNIT_Cm:
-      fValue *= 72 / 2.54f;
-      break;
-    case XFA_UNIT_Mp:
-      fValue *= 0.001f;
-      break;
-    case XFA_UNIT_Pc:
-      fValue *= 12.0f;
-      break;
-    default:
-      fValue = 0;
-      return FALSE;
-  }
-  switch (eUnit) {
-    case XFA_UNIT_Pt:
-      return TRUE;
-    case XFA_UNIT_Mm:
-      fValue /= 72 / 2.54f / 10;
-      return TRUE;
-    case XFA_UNIT_In:
-      fValue /= 72;
-      return TRUE;
-    case XFA_UNIT_Cm:
-      fValue /= 72 / 2.54f;
-      return TRUE;
-    case XFA_UNIT_Mp:
-      fValue /= 0.001f;
-      return TRUE;
-    case XFA_UNIT_Pc:
-      fValue /= 12.0f;
-      return TRUE;
-    default:
-      fValue = 0;
-      return FALSE;
-  }
-}
-XFA_UNIT CXFA_Measurement::GetUnit(const CFX_WideStringC& wsUnit) {
-  if (wsUnit == FX_WSTRC(L"mm")) {
-    return XFA_UNIT_Mm;
-  } else if (wsUnit == FX_WSTRC(L"pt")) {
-    return XFA_UNIT_Pt;
-  } else if (wsUnit == FX_WSTRC(L"in")) {
-    return XFA_UNIT_In;
-  } else if (wsUnit == FX_WSTRC(L"cm")) {
-    return XFA_UNIT_Cm;
-  } else if (wsUnit == FX_WSTRC(L"pc")) {
-    return XFA_UNIT_Pc;
-  } else if (wsUnit == FX_WSTRC(L"mp")) {
-    return XFA_UNIT_Mp;
-  } else if (wsUnit == FX_WSTRC(L"em")) {
-    return XFA_UNIT_Em;
-  } else if (wsUnit == FX_WSTRC(L"%")) {
-    return XFA_UNIT_Percent;
-  } else {
-    return XFA_UNIT_Unknown;
-  }
-}
-IFX_Stream* XFA_CreateWideTextRead(const CFX_WideString& wsBuffer) {
-  return new CXFA_WideTextRead(wsBuffer);
-}
-CXFA_WideTextRead::CXFA_WideTextRead(const CFX_WideString& wsBuffer)
-    : m_wsBuffer(wsBuffer), m_iPosition(0), m_iRefCount(1) {}
-void CXFA_WideTextRead::Release() {
-  if (--m_iRefCount < 1) {
-    delete this;
-  }
-}
-IFX_Stream* CXFA_WideTextRead::Retain() {
-  m_iRefCount++;
-  return this;
-}
-uint32_t CXFA_WideTextRead::GetAccessModes() const {
-  return FX_STREAMACCESS_Read | FX_STREAMACCESS_Text;
-}
-int32_t CXFA_WideTextRead::GetLength() const {
-  return m_wsBuffer.GetLength() * sizeof(FX_WCHAR);
-}
-int32_t CXFA_WideTextRead::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
-  switch (eSeek) {
-    case FX_STREAMSEEK_Begin:
-      m_iPosition = iOffset;
-      break;
-    case FX_STREAMSEEK_Current:
-      m_iPosition += iOffset;
-      break;
-    case FX_STREAMSEEK_End:
-      m_iPosition = m_wsBuffer.GetLength() + iOffset;
-      break;
-  }
-  if (m_iPosition < 0) {
-    m_iPosition = 0;
-  }
-  if (m_iPosition > m_wsBuffer.GetLength()) {
-    m_iPosition = m_wsBuffer.GetLength();
-  }
-  return GetPosition();
-}
-int32_t CXFA_WideTextRead::GetPosition() {
-  return m_iPosition * sizeof(FX_WCHAR);
-}
-FX_BOOL CXFA_WideTextRead::IsEOF() const {
-  return m_iPosition >= m_wsBuffer.GetLength();
-}
-int32_t CXFA_WideTextRead::ReadData(uint8_t* pBuffer, int32_t iBufferSize) {
-  return 0;
-}
-int32_t CXFA_WideTextRead::ReadString(FX_WCHAR* pStr,
-                                      int32_t iMaxLength,
-                                      FX_BOOL& bEOS) {
-  iMaxLength = std::min(iMaxLength, m_wsBuffer.GetLength() - m_iPosition);
-  if (iMaxLength == 0)
-    return 0;
-
-  FXSYS_wcsncpy(pStr, m_wsBuffer.c_str() + m_iPosition, iMaxLength);
-  m_iPosition += iMaxLength;
-  bEOS = IsEOF();
-  return iMaxLength;
-}
-int32_t CXFA_WideTextRead::WriteData(const uint8_t* pBuffer,
-                                     int32_t iBufferSize) {
-  return 0;
-}
-int32_t CXFA_WideTextRead::WriteString(const FX_WCHAR* pStr, int32_t iLength) {
-  return 0;
-}
-FX_BOOL CXFA_WideTextRead::SetLength(int32_t iLength) {
-  return FALSE;
-}
-int32_t CXFA_WideTextRead::GetBOM(uint8_t bom[4]) const {
-  return 0;
-}
-uint16_t CXFA_WideTextRead::GetCodePage() const {
-  return (sizeof(FX_WCHAR) == 2) ? FX_CODEPAGE_UTF16LE : FX_CODEPAGE_UTF32LE;
-}
-uint16_t CXFA_WideTextRead::SetCodePage(uint16_t wCodePage) {
-  return GetCodePage();
-}
-
-IFX_Stream* CXFA_WideTextRead::CreateSharedStream(uint32_t dwAccess,
-                                                  int32_t iOffset,
-                                                  int32_t iLength) {
-  return nullptr;
-}
-
-void CXFA_WideTextRead::Lock() {}
-
-void CXFA_WideTextRead::Unlock() {}
-
-CFX_WideString CXFA_WideTextRead::GetSrcText() const {
-  return m_wsBuffer;
-}
diff --git a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
index dad843c..d1f9b8e 100644
--- a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
+++ b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
@@ -10,7 +10,6 @@
 #include "xfa/fde/xml/fde_xml_imp.h"
 #include "xfa/fxfa/parser/cxfa_occur.h"
 #include "xfa/fxfa/parser/cxfa_scriptcontext.h"
-#include "xfa/fxfa/parser/xfa_basic_imp.h"
 #include "xfa/fxfa/parser/xfa_doclayout.h"
 #include "xfa/fxfa/parser/xfa_document.h"
 #include "xfa/fxfa/parser/xfa_document_layout_imp.h"
diff --git a/xfa/fxfa/parser/xfa_document_imp.cpp b/xfa/fxfa/parser/xfa_document_imp.cpp
index dcd98df..46a6edc 100644
--- a/xfa/fxfa/parser/xfa_document_imp.cpp
+++ b/xfa/fxfa/parser/xfa_document_imp.cpp
@@ -14,7 +14,6 @@
 #include "xfa/fxfa/parser/cscript_signaturepseudomodel.h"
 #include "xfa/fxfa/parser/cxfa_document_parser.h"
 #include "xfa/fxfa/parser/cxfa_scriptcontext.h"
-#include "xfa/fxfa/parser/xfa_basic_imp.h"
 #include "xfa/fxfa/parser/xfa_doclayout.h"
 #include "xfa/fxfa/parser/xfa_document.h"
 #include "xfa/fxfa/parser/xfa_document_layout_imp.h"
diff --git a/xfa/fxfa/parser/xfa_document_layout_imp.cpp b/xfa/fxfa/parser/xfa_document_layout_imp.cpp
index dc35657..ec407a2 100644
--- a/xfa/fxfa/parser/xfa_document_layout_imp.cpp
+++ b/xfa/fxfa/parser/xfa_document_layout_imp.cpp
@@ -6,7 +6,7 @@
 
 #include "xfa/fxfa/parser/xfa_document_layout_imp.h"
 
-#include "xfa/fxfa/parser/xfa_basic_imp.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
 #include "xfa/fxfa/parser/xfa_doclayout.h"
 #include "xfa/fxfa/parser/xfa_document.h"
 #include "xfa/fxfa/parser/xfa_document_datamerger_imp.h"
diff --git a/xfa/fxfa/parser/xfa_layout_itemlayout.cpp b/xfa/fxfa/parser/xfa_layout_itemlayout.cpp
index d56eac9..c120893 100644
--- a/xfa/fxfa/parser/xfa_layout_itemlayout.cpp
+++ b/xfa/fxfa/parser/xfa_layout_itemlayout.cpp
@@ -10,6 +10,7 @@
 #include <memory>
 
 #include "xfa/fxfa/app/xfa_ffnotify.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
 #include "xfa/fxfa/parser/cxfa_occur.h"
 #include "xfa/fxfa/parser/xfa_doclayout.h"
 #include "xfa/fxfa/parser/xfa_document.h"
diff --git a/xfa/fxfa/parser/xfa_layout_pagemgr_new.cpp b/xfa/fxfa/parser/xfa_layout_pagemgr_new.cpp
index f69c832..8794864 100644
--- a/xfa/fxfa/parser/xfa_layout_pagemgr_new.cpp
+++ b/xfa/fxfa/parser/xfa_layout_pagemgr_new.cpp
@@ -7,6 +7,7 @@
 #include "xfa/fxfa/parser/xfa_layout_pagemgr_new.h"
 
 #include "xfa/fxfa/app/xfa_ffnotify.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
 #include "xfa/fxfa/parser/cxfa_scriptcontext.h"
 #include "xfa/fxfa/parser/xfa_doclayout.h"
 #include "xfa/fxfa/parser/xfa_document.h"
diff --git a/xfa/fxfa/parser/xfa_utils.h b/xfa/fxfa/parser/xfa_utils.h
index 794624a..a5bdc90 100644
--- a/xfa/fxfa/parser/xfa_utils.h
+++ b/xfa/fxfa/parser/xfa_utils.h
@@ -170,7 +170,6 @@
 void XFA_GetPlainTextFromRichText(CFDE_XMLNode* pXMLNode,
                                   CFX_WideString& wsPlainText);
 FX_BOOL XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode);
-IFX_Stream* XFA_CreateWideTextRead(const CFX_WideString& wsBuffer);
 
 void XFA_DataExporter_DealWithDataGroupNode(CXFA_Node* pDataNode);
 void XFA_DataExporter_RegenerateFormFile(CXFA_Node* pNode,
@@ -178,4 +177,36 @@
                                          const FX_CHAR* pChecksum = nullptr,
                                          FX_BOOL bSaveXML = FALSE);
 
+const XFA_NOTSUREATTRIBUTE* XFA_GetNotsureAttribute(
+    XFA_Element eElement,
+    XFA_ATTRIBUTE eAttribute,
+    XFA_ATTRIBUTETYPE eType = XFA_ATTRIBUTETYPE_NOTSURE);
+
+const XFA_SCRIPTATTRIBUTEINFO* XFA_GetScriptAttributeByName(
+    XFA_Element eElement,
+    const CFX_WideStringC& wsAttributeName);
+
+const XFA_PROPERTY* XFA_GetPropertyOfElement(XFA_Element eElement,
+                                             XFA_Element eProperty,
+                                             uint32_t dwPacket);
+const XFA_PROPERTY* XFA_GetElementProperties(XFA_Element eElement,
+                                             int32_t& iCount);
+const uint8_t* XFA_GetElementAttributes(XFA_Element eElement, int32_t& iCount);
+const XFA_ELEMENTINFO* XFA_GetElementByID(XFA_Element eName);
+XFA_Element XFA_GetElementTypeForName(const CFX_WideStringC& wsName);
+CXFA_Measurement XFA_GetAttributeDefaultValue_Measure(XFA_Element eElement,
+                                                      XFA_ATTRIBUTE eAttribute,
+                                                      uint32_t dwPacket);
+FX_BOOL XFA_GetAttributeDefaultValue(void*& pValue,
+                                     XFA_Element eElement,
+                                     XFA_ATTRIBUTE eAttribute,
+                                     XFA_ATTRIBUTETYPE eType,
+                                     uint32_t dwPacket);
+const XFA_ATTRIBUTEINFO* XFA_GetAttributeByName(const CFX_WideStringC& wsName);
+const XFA_ATTRIBUTEINFO* XFA_GetAttributeByID(XFA_ATTRIBUTE eName);
+const XFA_ATTRIBUTEENUMINFO* XFA_GetAttributeEnumByName(
+    const CFX_WideStringC& wsName);
+const XFA_PACKETINFO* XFA_GetPacketByIndex(XFA_PACKET ePacket);
+const XFA_PACKETINFO* XFA_GetPacketByID(uint32_t dwPacket);
+
 #endif  // XFA_FXFA_PARSER_XFA_UTILS_H_
diff --git a/xfa/fxfa/parser/xfa_utils_imp.cpp b/xfa/fxfa/parser/xfa_utils_imp.cpp
index 2f9c3e0..50438b7 100644
--- a/xfa/fxfa/parser/xfa_utils_imp.cpp
+++ b/xfa/fxfa/parser/xfa_utils_imp.cpp
@@ -8,6 +8,8 @@
 
 #include "core/fxcrt/include/fx_ext.h"
 #include "xfa/fde/xml/fde_xml_imp.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
+#include "xfa/fxfa/parser/xfa_basic_data.h"
 #include "xfa/fxfa/parser/xfa_doclayout.h"
 #include "xfa/fxfa/parser/xfa_document.h"
 #include "xfa/fxfa/parser/xfa_localemgr.h"
@@ -202,11 +204,12 @@
     XFA_GetPlainTextFromRichText(pChildXML, wsPlainText);
   }
 }
+
 FX_BOOL XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode) {
   FX_BOOL bRet = FALSE;
-  if (!pFieldNode) {
+  if (!pFieldNode)
     return bRet;
-  }
+
   CXFA_Node* pUIChild = pFieldNode->GetChild(0, XFA_Element::Ui);
   if (pUIChild) {
     CXFA_Node* pFirstChild = pUIChild->GetNodeItem(XFA_NODEITEM_FirstChild);
@@ -229,3 +232,256 @@
   nRotation = nRotation < 0 ? nRotation + 360 : nRotation;
   return nRotation;
 }
+
+const XFA_SCRIPTATTRIBUTEINFO* XFA_GetScriptAttributeByName(
+    XFA_Element eElement,
+    const CFX_WideStringC& wsAttributeName) {
+  if (wsAttributeName.IsEmpty())
+    return nullptr;
+
+  int32_t iElementIndex = static_cast<int32_t>(eElement);
+  while (iElementIndex != -1) {
+    const XFA_SCRIPTHIERARCHY* scriptIndex = g_XFAScriptIndex + iElementIndex;
+    int32_t icount = scriptIndex->wAttributeCount;
+    if (icount == 0) {
+      iElementIndex = scriptIndex->wParentIndex;
+      continue;
+    }
+    uint32_t uHash = FX_HashCode_GetW(wsAttributeName, false);
+    int32_t iStart = scriptIndex->wAttributeStart, iEnd = iStart + icount - 1;
+    do {
+      int32_t iMid = (iStart + iEnd) / 2;
+      const XFA_SCRIPTATTRIBUTEINFO* pInfo = g_SomAttributeData + iMid;
+      if (uHash == pInfo->uHash)
+        return pInfo;
+      if (uHash < pInfo->uHash)
+        iEnd = iMid - 1;
+      else
+        iStart = iMid + 1;
+    } while (iStart <= iEnd);
+    iElementIndex = scriptIndex->wParentIndex;
+  }
+  return nullptr;
+}
+
+const XFA_NOTSUREATTRIBUTE* XFA_GetNotsureAttribute(XFA_Element eElement,
+                                                    XFA_ATTRIBUTE eAttribute,
+                                                    XFA_ATTRIBUTETYPE eType) {
+  int32_t iStart = 0, iEnd = g_iXFANotsureCount - 1;
+  do {
+    int32_t iMid = (iStart + iEnd) / 2;
+    const XFA_NOTSUREATTRIBUTE* pAttr = g_XFANotsureAttributes + iMid;
+    if (eElement == pAttr->eElement) {
+      if (pAttr->eAttribute == eAttribute) {
+        if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType)
+          return pAttr;
+        return nullptr;
+      }
+      int32_t iBefore = iMid - 1;
+      if (iBefore >= 0) {
+        pAttr = g_XFANotsureAttributes + iBefore;
+        while (eElement == pAttr->eElement) {
+          if (pAttr->eAttribute == eAttribute) {
+            if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType)
+              return pAttr;
+            return nullptr;
+          }
+          iBefore--;
+          if (iBefore < 0)
+            break;
+
+          pAttr = g_XFANotsureAttributes + iBefore;
+        }
+      }
+
+      int32_t iAfter = iMid + 1;
+      if (iAfter <= g_iXFANotsureCount - 1) {
+        pAttr = g_XFANotsureAttributes + iAfter;
+        while (eElement == pAttr->eElement) {
+          if (pAttr->eAttribute == eAttribute) {
+            if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType)
+              return pAttr;
+            return nullptr;
+          }
+          iAfter++;
+          if (iAfter > g_iXFANotsureCount - 1)
+            break;
+
+          pAttr = g_XFANotsureAttributes + iAfter;
+        }
+      }
+      return nullptr;
+    }
+
+    if (eElement < pAttr->eElement)
+      iEnd = iMid - 1;
+    else
+      iStart = iMid + 1;
+  } while (iStart <= iEnd);
+  return nullptr;
+}
+
+const XFA_PROPERTY* XFA_GetPropertyOfElement(XFA_Element eElement,
+                                             XFA_Element eProperty,
+                                             uint32_t dwPacket) {
+  int32_t iCount = 0;
+  const XFA_PROPERTY* pProperties = XFA_GetElementProperties(eElement, iCount);
+  if (!pProperties || iCount < 1)
+    return nullptr;
+
+  auto it = std::find_if(pProperties, pProperties + iCount,
+                         [eProperty](const XFA_PROPERTY& prop) {
+                           return prop.eName == eProperty;
+                         });
+  if (it == pProperties + iCount)
+    return nullptr;
+
+  const XFA_ELEMENTINFO* pInfo = XFA_GetElementByID(eProperty);
+  ASSERT(pInfo);
+  if (dwPacket != XFA_XDPPACKET_UNKNOWN && !(dwPacket & pInfo->dwPackets))
+    return nullptr;
+  return it;
+}
+
+const XFA_PROPERTY* XFA_GetElementProperties(XFA_Element eElement,
+                                             int32_t& iCount) {
+  if (eElement == XFA_Element::Unknown)
+    return nullptr;
+
+  const XFA_ELEMENTHIERARCHY* pElement =
+      g_XFAElementPropertyIndex + static_cast<int32_t>(eElement);
+  iCount = pElement->wCount;
+  return g_XFAElementPropertyData + pElement->wStart;
+}
+
+const uint8_t* XFA_GetElementAttributes(XFA_Element eElement, int32_t& iCount) {
+  if (eElement == XFA_Element::Unknown)
+    return nullptr;
+
+  const XFA_ELEMENTHIERARCHY* pElement =
+      g_XFAElementAttributeIndex + static_cast<int32_t>(eElement);
+  iCount = pElement->wCount;
+  return g_XFAElementAttributeData + pElement->wStart;
+}
+
+const XFA_ELEMENTINFO* XFA_GetElementByID(XFA_Element eName) {
+  return eName != XFA_Element::Unknown
+             ? g_XFAElementData + static_cast<int32_t>(eName)
+             : nullptr;
+}
+
+XFA_Element XFA_GetElementTypeForName(const CFX_WideStringC& wsName) {
+  if (wsName.IsEmpty())
+    return XFA_Element::Unknown;
+
+  uint32_t uHash = FX_HashCode_GetW(wsName, false);
+  const XFA_ELEMENTINFO* pEnd = g_XFAElementData + g_iXFAElementCount;
+  auto pInfo = std::lower_bound(g_XFAElementData, pEnd, uHash,
+                                [](const XFA_ELEMENTINFO& info, uint32_t hash) {
+                                  return info.uHash < hash;
+                                });
+  if (pInfo < pEnd && pInfo->uHash == uHash)
+    return pInfo->eName;
+  return XFA_Element::Unknown;
+}
+
+CXFA_Measurement XFA_GetAttributeDefaultValue_Measure(XFA_Element eElement,
+                                                      XFA_ATTRIBUTE eAttribute,
+                                                      uint32_t dwPacket) {
+  void* pValue;
+  if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
+                                   XFA_ATTRIBUTETYPE_Measure, dwPacket)) {
+    return *(CXFA_Measurement*)pValue;
+  }
+  return CXFA_Measurement();
+}
+
+FX_BOOL XFA_GetAttributeDefaultValue(void*& pValue,
+                                     XFA_Element eElement,
+                                     XFA_ATTRIBUTE eAttribute,
+                                     XFA_ATTRIBUTETYPE eType,
+                                     uint32_t dwPacket) {
+  const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttribute);
+  if (!pInfo)
+    return FALSE;
+  if (dwPacket && (dwPacket & pInfo->dwPackets) == 0)
+    return FALSE;
+  if (pInfo->eType == eType) {
+    pValue = pInfo->pDefValue;
+    return TRUE;
+  }
+  if (pInfo->eType == XFA_ATTRIBUTETYPE_NOTSURE) {
+    const XFA_NOTSUREATTRIBUTE* pAttr =
+        XFA_GetNotsureAttribute(eElement, eAttribute, eType);
+    if (pAttr) {
+      pValue = pAttr->pValue;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+const XFA_ATTRIBUTEINFO* XFA_GetAttributeByName(const CFX_WideStringC& wsName) {
+  if (wsName.IsEmpty())
+    return nullptr;
+
+  uint32_t uHash = FX_HashCode_GetW(wsName, false);
+  int32_t iStart = 0;
+  int32_t iEnd = g_iXFAAttributeCount - 1;
+  do {
+    int32_t iMid = (iStart + iEnd) / 2;
+    const XFA_ATTRIBUTEINFO* pInfo = g_XFAAttributeData + iMid;
+    if (uHash == pInfo->uHash)
+      return pInfo;
+    if (uHash < pInfo->uHash)
+      iEnd = iMid - 1;
+    else
+      iStart = iMid + 1;
+  } while (iStart <= iEnd);
+  return nullptr;
+}
+
+const XFA_ATTRIBUTEINFO* XFA_GetAttributeByID(XFA_ATTRIBUTE eName) {
+  return (eName < g_iXFAAttributeCount) ? (g_XFAAttributeData + eName)
+                                        : nullptr;
+}
+
+const XFA_ATTRIBUTEENUMINFO* XFA_GetAttributeEnumByName(
+    const CFX_WideStringC& wsName) {
+  if (wsName.IsEmpty())
+    return nullptr;
+
+  uint32_t uHash = FX_HashCode_GetW(wsName, false);
+  int32_t iStart = 0;
+  int32_t iEnd = g_iXFAEnumCount - 1;
+  do {
+    int32_t iMid = (iStart + iEnd) / 2;
+    const XFA_ATTRIBUTEENUMINFO* pInfo = g_XFAEnumData + iMid;
+    if (uHash == pInfo->uHash)
+      return pInfo;
+    if (uHash < pInfo->uHash)
+      iEnd = iMid - 1;
+    else
+      iStart = iMid + 1;
+  } while (iStart <= iEnd);
+  return nullptr;
+}
+
+const XFA_PACKETINFO* XFA_GetPacketByIndex(XFA_PACKET ePacket) {
+  return g_XFAPacketData + ePacket;
+}
+
+const XFA_PACKETINFO* XFA_GetPacketByID(uint32_t dwPacket) {
+  int32_t iStart = 0, iEnd = g_iXFAPacketCount - 1;
+  do {
+    int32_t iMid = (iStart + iEnd) / 2;
+    uint32_t dwFind = (g_XFAPacketData + iMid)->eName;
+    if (dwPacket == dwFind)
+      return g_XFAPacketData + iMid;
+    if (dwPacket < dwFind)
+      iEnd = iMid - 1;
+    else
+      iStart = iMid + 1;
+  } while (iStart <= iEnd);
+  return nullptr;
+}