Add helpers to get attribute information

This CL adds helpers to CXFA_Node to get the type of an attribute and
the default value for a given attribute.

Change-Id: I8bf41f568fe1da650fb3df4232b63d2e48038e07
Reviewed-on: https://pdfium-review.googlesource.com/19330
Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
Commit-Queue: dsinclair <dsinclair@chromium.org>
diff --git a/fxjs/cjx_node.cpp b/fxjs/cjx_node.cpp
index f01ead6..e81a239 100644
--- a/fxjs/cjx_node.cpp
+++ b/fxjs/cjx_node.cpp
@@ -190,33 +190,25 @@
 bool CJX_Node::SetAttribute(XFA_Attribute eAttr,
                             const WideStringView& wsValue,
                             bool bNotify) {
-  const XFA_ATTRIBUTEINFO* pAttr = XFA_GetAttributeByID(eAttr);
-
-  XFA_AttributeType eType = pAttr->eType;
-  if (eType == XFA_AttributeType::NotSure) {
-    const XFA_NOTSUREATTRIBUTE* pNotsure =
-        XFA_GetNotsureAttribute(GetXFANode()->GetElementType(), pAttr->eName);
-    eType = pNotsure ? pNotsure->eType : XFA_AttributeType::CData;
-  }
+  XFA_AttributeType eType = GetXFANode()->GetAttributeType(eAttr);
   switch (eType) {
     case XFA_AttributeType::Enum: {
       const XFA_ATTRIBUTEENUMINFO* pEnum = XFA_GetAttributeEnumByName(wsValue);
-      return SetEnum(pAttr->eName,
-                     pEnum ? pEnum->eName
-                           : (XFA_ATTRIBUTEENUM)(intptr_t)(pAttr->pDefValue),
-                     bNotify);
+      return SetEnum(
+          eAttr, pEnum ? pEnum->eName : *(GetXFANode()->GetDefaultEnum(eAttr)),
+          bNotify);
     } break;
     case XFA_AttributeType::CData:
-      return SetCData(pAttr->eName, WideString(wsValue), bNotify, false);
+      return SetCData(eAttr, WideString(wsValue), bNotify, false);
     case XFA_AttributeType::Boolean:
-      return SetBoolean(pAttr->eName, wsValue != L"0", bNotify);
+      return SetBoolean(eAttr, wsValue != L"0", bNotify);
     case XFA_AttributeType::Integer:
-      return SetInteger(pAttr->eName,
+      return SetInteger(eAttr,
                         FXSYS_round(FXSYS_wcstof(wsValue.unterminated_c_str(),
                                                  wsValue.GetLength(), nullptr)),
                         bNotify);
     case XFA_AttributeType::Measure:
-      return SetMeasure(pAttr->eName, CXFA_Measurement(wsValue), bNotify);
+      return SetMeasure(eAttr, CXFA_Measurement(wsValue), bNotify);
     default:
       break;
   }
@@ -245,41 +237,32 @@
 
 pdfium::Optional<WideString> CJX_Node::TryAttribute(XFA_Attribute eAttr,
                                                     bool bUseDefault) {
-  const XFA_ATTRIBUTEINFO* pAttr = XFA_GetAttributeByID(eAttr);
-
-  XFA_AttributeType eType = pAttr->eType;
-  if (eType == XFA_AttributeType::NotSure) {
-    const XFA_NOTSUREATTRIBUTE* pNotsure =
-        XFA_GetNotsureAttribute(GetXFANode()->GetElementType(), pAttr->eName);
-    eType = pNotsure ? pNotsure->eType : XFA_AttributeType::CData;
-  }
+  XFA_AttributeType eType = GetXFANode()->GetAttributeType(eAttr);
   switch (eType) {
     case XFA_AttributeType::Enum: {
-      pdfium::Optional<XFA_ATTRIBUTEENUM> value =
-          TryEnum(pAttr->eName, bUseDefault);
+      pdfium::Optional<XFA_ATTRIBUTEENUM> value = TryEnum(eAttr, bUseDefault);
       if (!value)
         return {};
 
       return {GetAttributeEnumByID(*value)->pName};
     }
     case XFA_AttributeType::CData:
-      return TryCData(pAttr->eName, bUseDefault);
+      return TryCData(eAttr, bUseDefault);
 
     case XFA_AttributeType::Boolean: {
-      pdfium::Optional<bool> value = TryBoolean(pAttr->eName, bUseDefault);
+      pdfium::Optional<bool> value = TryBoolean(eAttr, bUseDefault);
       if (!value)
         return {};
       return {*value ? L"1" : L"0"};
     }
     case XFA_AttributeType::Integer: {
-      pdfium::Optional<int32_t> iValue = TryInteger(pAttr->eName, bUseDefault);
+      pdfium::Optional<int32_t> iValue = TryInteger(eAttr, bUseDefault);
       if (!iValue)
         return {};
       return {WideString::Format(L"%d", *iValue)};
     }
     case XFA_AttributeType::Measure: {
-      pdfium::Optional<CXFA_Measurement> value =
-          TryMeasure(pAttr->eName, bUseDefault);
+      pdfium::Optional<CXFA_Measurement> value = TryMeasure(eAttr, bUseDefault);
       if (!value)
         return {};
 
@@ -3118,11 +3101,10 @@
     }
     return true;
   }
-
-  const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttr);
   ASSERT(elem->GetType() == FX_XMLNODE_Element);
-  WideString wsAttrName = pInfo->pName;
-  if (pInfo->eName == XFA_Attribute::ContentType)
+
+  WideString wsAttrName = CXFA_Node::AttributeToName(eAttr);
+  if (eAttr == XFA_Attribute::ContentType)
     wsAttrName = L"xfa:" + wsAttrName;
 
   elem->SetString(wsAttrName, wsValue);
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index ee2a6df..f11876f 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -333,6 +333,17 @@
   return *(m_Attributes + i);
 }
 
+XFA_AttributeType CXFA_Node::GetAttributeType(XFA_Attribute type) const {
+  const XFA_ATTRIBUTEINFO* attr = XFA_GetAttributeByID(type);
+  XFA_AttributeType eType = attr->eType;
+  if (eType != XFA_AttributeType::NotSure)
+    return eType;
+
+  const XFA_NOTSUREATTRIBUTE* pNotsure =
+      XFA_GetNotsureAttribute(GetElementType(), attr->eName);
+  return pNotsure ? pNotsure->eType : XFA_AttributeType::CData;
+}
+
 CXFA_Node* CXFA_Node::GetNodeItem(XFA_NODEITEM eItem,
                                   XFA_ObjectType eType) const {
   CXFA_Node* pNode = nullptr;
@@ -1318,56 +1329,69 @@
 }
 
 pdfium::Optional<bool> CXFA_Node::GetDefaultBoolean(XFA_Attribute attr) const {
-  void* pValue = nullptr;
-  if (!XFA_GetAttributeDefaultValue(pValue, GetElementType(), attr,
-                                    XFA_AttributeType::Boolean,
-                                    GetPacketID())) {
+  pdfium::Optional<void*> value =
+      GetDefaultValue(attr, XFA_AttributeType::Boolean);
+  if (!value)
     return {};
-  }
-  return {!!pValue};
+  return {!!*value};
 }
 
 pdfium::Optional<int32_t> CXFA_Node::GetDefaultInteger(
     XFA_Attribute attr) const {
-  void* pValue = nullptr;
-  if (!XFA_GetAttributeDefaultValue(pValue, GetElementType(), attr,
-                                    XFA_AttributeType::Integer,
-                                    GetPacketID())) {
+  pdfium::Optional<void*> value =
+      GetDefaultValue(attr, XFA_AttributeType::Integer);
+  if (!value)
     return {};
-  }
-  return {static_cast<int32_t>(reinterpret_cast<uintptr_t>(pValue))};
+  return {static_cast<int32_t>(reinterpret_cast<uintptr_t>(*value))};
 }
 
 pdfium::Optional<CXFA_Measurement> CXFA_Node::GetDefaultMeasurement(
     XFA_Attribute attr) const {
-  void* pValue = nullptr;
-  if (!XFA_GetAttributeDefaultValue(pValue, GetElementType(), attr,
-                                    XFA_AttributeType::Measure,
-                                    GetPacketID())) {
+  pdfium::Optional<void*> value =
+      GetDefaultValue(attr, XFA_AttributeType::Measure);
+  if (!value)
     return {};
-  }
+
   CXFA_Measurement measure;
-  memcpy(&measure, pValue, sizeof(measure));
+  memcpy(&measure, *value, sizeof(measure));
   return {measure};
 }
 
 pdfium::Optional<WideString> CXFA_Node::GetDefaultCData(
     XFA_Attribute attr) const {
-  void* pValue = nullptr;
-  if (!XFA_GetAttributeDefaultValue(pValue, GetElementType(), attr,
-                                    XFA_AttributeType::CData, GetPacketID())) {
+  pdfium::Optional<void*> value =
+      GetDefaultValue(attr, XFA_AttributeType::CData);
+  if (!value)
     return {};
-  }
-  WideStringView view((const wchar_t*)pValue);
-  return {WideString(view)};
+
+  return {WideString(static_cast<const wchar_t*>(*value))};
 }
 
 pdfium::Optional<XFA_ATTRIBUTEENUM> CXFA_Node::GetDefaultEnum(
     XFA_Attribute attr) const {
-  void* pValue = nullptr;
-  if (!XFA_GetAttributeDefaultValue(pValue, GetElementType(), attr,
-                                    XFA_AttributeType::Enum, GetPacketID())) {
+  pdfium::Optional<void*> value =
+      GetDefaultValue(attr, XFA_AttributeType::Enum);
+  if (!value)
     return {};
-  }
-  return {static_cast<XFA_ATTRIBUTEENUM>(reinterpret_cast<uintptr_t>(pValue))};
+  return {static_cast<XFA_ATTRIBUTEENUM>(reinterpret_cast<uintptr_t>(*value))};
+}
+
+pdfium::Optional<void*> CXFA_Node::GetDefaultValue(
+    XFA_Attribute attr,
+    XFA_AttributeType eType) const {
+  const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(attr);
+  if (!pInfo)
+    return {};
+  if (GetPacketID() && (GetPacketID() & pInfo->dwPackets) == 0)
+    return {};
+  if (pInfo->eType == eType)
+    return {pInfo->pDefValue};
+  if (pInfo->eType != XFA_AttributeType::NotSure)
+    return {};
+
+  const XFA_NOTSUREATTRIBUTE* pAttr =
+      XFA_GetNotsureAttribute(GetElementType(), attr, eType);
+  if (pAttr)
+    return {pAttr->pValue};
+  return {};
 }
diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h
index e5f47a1..7465f31 100644
--- a/xfa/fxfa/parser/cxfa_node.h
+++ b/xfa/fxfa/parser/cxfa_node.h
@@ -70,6 +70,7 @@
 
   bool HasAttribute(XFA_Attribute attr) const;
   XFA_Attribute GetAttribute(size_t i) const;
+  XFA_AttributeType GetAttributeType(XFA_Attribute type) const;
 
   uint32_t GetPacketID() const { return m_ePacket; }
 
@@ -183,6 +184,8 @@
   const PropertyData* GetPropertyData(XFA_Element property) const;
   pdfium::Optional<XFA_Element> GetFirstPropertyWithFlag(uint8_t flag);
   void OnRemoved(bool bNotify);
+  pdfium::Optional<void*> GetDefaultValue(XFA_Attribute attr,
+                                          XFA_AttributeType eType) const;
 
   const PropertyData* m_Properties;
   const XFA_Attribute* m_Attributes;
diff --git a/xfa/fxfa/parser/xfa_utils.cpp b/xfa/fxfa/parser/xfa_utils.cpp
index 7fb5ff5..2f5b479 100644
--- a/xfa/fxfa/parser/xfa_utils.cpp
+++ b/xfa/fxfa/parser/xfa_utils.cpp
@@ -243,31 +243,6 @@
   return nullptr;
 }
 
-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_GetAttributeByID(XFA_Attribute eName) {
   ASSERT(static_cast<uint8_t>(eName) < g_iXFAAttributeCount);
   return g_XFAAttributeData + static_cast<uint8_t>(eName);
diff --git a/xfa/fxfa/parser/xfa_utils.h b/xfa/fxfa/parser/xfa_utils.h
index afc1076..7a7eb15 100644
--- a/xfa/fxfa/parser/xfa_utils.h
+++ b/xfa/fxfa/parser/xfa_utils.h
@@ -49,11 +49,6 @@
 
 const XFA_Attribute* XFA_GetElementAttributes(XFA_Element eElement,
                                               int32_t& iCount);
-bool XFA_GetAttributeDefaultValue(void*& pValue,
-                                  XFA_Element eElement,
-                                  XFA_Attribute eAttribute,
-                                  XFA_AttributeType eType,
-                                  uint32_t dwPacket);
 const XFA_ATTRIBUTEINFO* XFA_GetAttributeByID(XFA_Attribute eName);
 const XFA_ATTRIBUTEENUMINFO* XFA_GetAttributeEnumByName(
     const WideStringView& wsName);