1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #include "msgCore.h"
7 #include "nsMsgFolderCacheElement.h"
8 #include "prmem.h"
9 #include "nsMsgUtils.h"
10 
nsMsgFolderCacheElement()11 nsMsgFolderCacheElement::nsMsgFolderCacheElement() {
12   m_mdbRow = nullptr;
13   m_owningCache = nullptr;
14 }
15 
~nsMsgFolderCacheElement()16 nsMsgFolderCacheElement::~nsMsgFolderCacheElement() {}
17 
NS_IMPL_ISUPPORTS(nsMsgFolderCacheElement,nsIMsgFolderCacheElement)18 NS_IMPL_ISUPPORTS(nsMsgFolderCacheElement, nsIMsgFolderCacheElement)
19 
20 NS_IMETHODIMP nsMsgFolderCacheElement::GetKey(nsACString& aFolderKey) {
21   aFolderKey = m_folderKey;
22   return NS_OK;
23 }
24 
SetKey(const nsACString & aFolderKey)25 NS_IMETHODIMP nsMsgFolderCacheElement::SetKey(const nsACString& aFolderKey) {
26   m_folderKey = aFolderKey;
27   return NS_OK;
28 }
29 
SetOwningCache(nsMsgFolderCache * owningCache)30 void nsMsgFolderCacheElement::SetOwningCache(nsMsgFolderCache* owningCache) {
31   m_owningCache = owningCache;
32 }
33 
GetStringProperty(const char * propertyName,nsACString & result)34 NS_IMETHODIMP nsMsgFolderCacheElement::GetStringProperty(
35     const char* propertyName, nsACString& result) {
36   NS_ENSURE_ARG_POINTER(propertyName);
37   NS_ENSURE_TRUE(m_mdbRow && m_owningCache, NS_ERROR_FAILURE);
38 
39   mdb_token property_token;
40   nsresult ret = m_owningCache->GetStore()->StringToToken(
41       m_owningCache->GetEnv(), propertyName, &property_token);
42   if (NS_SUCCEEDED(ret))
43     ret =
44         m_owningCache->RowCellColumnToCharPtr(m_mdbRow, property_token, result);
45   return ret;
46 }
47 
GetInt32Property(const char * propertyName,int32_t * aResult)48 NS_IMETHODIMP nsMsgFolderCacheElement::GetInt32Property(
49     const char* propertyName, int32_t* aResult) {
50   NS_ENSURE_ARG_POINTER(propertyName);
51   NS_ENSURE_ARG_POINTER(aResult);
52   NS_ENSURE_TRUE(m_mdbRow, NS_ERROR_FAILURE);
53 
54   nsCString resultStr;
55   GetStringProperty(propertyName, resultStr);
56   if (resultStr.IsEmpty()) return NS_ERROR_FAILURE;
57 
58   // This must be an inverse function to nsCString.AppentInt(),
59   // which uses snprintf("%x") internally, so that the wrapped negative numbers
60   // are decoded properly.
61   if (PR_sscanf(resultStr.get(), "%x", aResult) != 1) {
62     NS_WARNING("Unexpected failure to decode hex string.");
63     return NS_ERROR_FAILURE;
64   }
65 
66   return NS_OK;
67 }
68 
GetInt64Property(const char * propertyName,int64_t * aResult)69 NS_IMETHODIMP nsMsgFolderCacheElement::GetInt64Property(
70     const char* propertyName, int64_t* aResult) {
71   NS_ENSURE_ARG_POINTER(propertyName);
72   NS_ENSURE_ARG_POINTER(aResult);
73   NS_ENSURE_TRUE(m_mdbRow, NS_ERROR_FAILURE);
74 
75   nsCString resultStr;
76   GetStringProperty(propertyName, resultStr);
77   if (resultStr.IsEmpty()) return NS_ERROR_FAILURE;
78 
79   // This must be an inverse function to nsCString.AppentInt(),
80   // which uses snprintf("%x") internally, so that the wrapped negative numbers
81   // are decoded properly.
82   if (PR_sscanf(resultStr.get(), "%llx", aResult) != 1) {
83     NS_WARNING("Unexpected failure to decode hex string.");
84     return NS_ERROR_FAILURE;
85   }
86 
87   return NS_OK;
88 }
89 
SetStringProperty(const char * propertyName,const nsACString & propertyValue)90 NS_IMETHODIMP nsMsgFolderCacheElement::SetStringProperty(
91     const char* propertyName, const nsACString& propertyValue) {
92   NS_ENSURE_ARG_POINTER(propertyName);
93   NS_ENSURE_TRUE(m_mdbRow, NS_ERROR_FAILURE);
94   nsresult rv = NS_OK;
95   mdb_token property_token;
96 
97   if (m_owningCache) {
98     rv = m_owningCache->GetStore()->StringToToken(
99         m_owningCache->GetEnv(), propertyName, &property_token);
100     if (NS_SUCCEEDED(rv)) {
101       struct mdbYarn yarn;
102 
103       yarn.mYarn_Grow = NULL;
104       if (m_mdbRow) {
105         nsCString propertyVal(propertyValue);
106         yarn.mYarn_Buf = (void*)propertyVal.get();
107         yarn.mYarn_Size = strlen((const char*)yarn.mYarn_Buf) + 1;
108         yarn.mYarn_Fill = yarn.mYarn_Size - 1;
109         yarn.mYarn_Form =
110             0;  // what to do with this? we're storing csid in the msg hdr...
111         rv =
112             m_mdbRow->AddColumn(m_owningCache->GetEnv(), property_token, &yarn);
113         return rv;
114       }
115     }
116   }
117   return rv;
118 }
119 
SetInt32Property(const char * propertyName,int32_t propertyValue)120 NS_IMETHODIMP nsMsgFolderCacheElement::SetInt32Property(
121     const char* propertyName, int32_t propertyValue) {
122   NS_ENSURE_ARG_POINTER(propertyName);
123   NS_ENSURE_TRUE(m_mdbRow, NS_ERROR_FAILURE);
124 
125   // This also supports encoding negative numbers into hex
126   // by integer wrapping them (e.g. -1 -> "ffffffff").
127   nsAutoCString propertyStr;
128   propertyStr.AppendInt(propertyValue, 16);
129   return SetStringProperty(propertyName, propertyStr);
130 }
131 
SetInt64Property(const char * propertyName,int64_t propertyValue)132 NS_IMETHODIMP nsMsgFolderCacheElement::SetInt64Property(
133     const char* propertyName, int64_t propertyValue) {
134   NS_ENSURE_ARG_POINTER(propertyName);
135   NS_ENSURE_TRUE(m_mdbRow, NS_ERROR_FAILURE);
136 
137   // This also supports encoding negative numbers into hex
138   // by integer wrapping them (e.g. -1 -> "ffffffffffffffff").
139   nsAutoCString propertyStr;
140   propertyStr.AppendInt(propertyValue, 16);
141   return SetStringProperty(propertyName, propertyStr);
142 }
143 
SetMDBRow(nsIMdbRow * row)144 void nsMsgFolderCacheElement::SetMDBRow(nsIMdbRow* row) { m_mdbRow = row; }
145