Index: chrome/browser/chromeos/gdata/gdata_operations.cc |
diff --git a/chrome/browser/chromeos/gdata/gdata_operations.cc b/chrome/browser/chromeos/gdata/gdata_operations.cc |
index 5c4adf5f14bd81b9536f884963b4d5a02853fd40..ec050e6d98b9d5307e70a27f3821e3db4146d9a4 100644 |
--- a/chrome/browser/chromeos/gdata/gdata_operations.cc |
+++ b/chrome/browser/chromeos/gdata/gdata_operations.cc |
@@ -160,6 +160,28 @@ GURL FormatDocumentListURL(const std::string& directory_resource_id) { |
directory_resource_id).c_str())); |
} |
+// Parse JSON string to base::Value object. |
+void ParseJsonOnBlockingPool(const std::string& data, |
+ scoped_ptr<base::Value>* value) { |
+ DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ int error_code = -1; |
+ std::string error_message; |
+ value->reset(base::JSONReader::ReadAndReturnError(data, |
+ base::JSON_PARSE_RFC, |
+ &error_code, |
+ &error_message)); |
+ |
+ if (!value->get()) { |
+ LOG(ERROR) << "Error while parsing entry response: " |
+ << error_message |
+ << ", code: " |
+ << error_code |
+ << ", data:\n" |
+ << data; |
+ } |
+} |
+ |
} // namespace |
namespace gdata { |
@@ -456,25 +478,19 @@ GetDataOperation::~GetDataOperation() {} |
bool GetDataOperation::ProcessURLFetchResults(const net::URLFetcher* source) { |
std::string data; |
source->GetResponseAsString(&data); |
- scoped_ptr<base::Value> root_value; |
GDataErrorCode code = GetErrorCode(source); |
+ bool ret = false; |
switch (code) { |
case HTTP_SUCCESS: |
- case HTTP_CREATED: { |
- root_value.reset(ParseResponse(data)); |
- if (!root_value.get()) |
- code = GDATA_PARSE_ERROR; |
- |
+ case HTTP_CREATED: |
+ ret = ParseResponse(code, data); |
break; |
- } |
default: |
hashimoto
2012/07/10 03:48:39
Shouldn't we call the callback on error cases?
yoshiki
2012/07/11 00:47:14
Done.
|
break; |
} |
- if (!callback_.is_null()) |
- callback_.Run(code, root_value.Pass()); |
- return root_value.get() != NULL; |
+ return ret; |
} |
void GetDataOperation::RunCallbackOnPrematureFailure(GDataErrorCode code) { |
@@ -484,21 +500,44 @@ void GetDataOperation::RunCallbackOnPrematureFailure(GDataErrorCode code) { |
} |
} |
-base::Value* GetDataOperation::ParseResponse(const std::string& data) { |
- int error_code = -1; |
- std::string error_message; |
- scoped_ptr<base::Value> root_value(base::JSONReader::ReadAndReturnError( |
- data, base::JSON_PARSE_RFC, &error_code, &error_message)); |
- if (!root_value.get()) { |
- LOG(ERROR) << "Error while parsing entry response: " |
- << error_message |
- << ", code: " |
- << error_code |
- << ", data:\n" |
- << data; |
- return NULL; |
- } |
- return root_value.release(); |
+bool GetDataOperation::ParseResponse(GDataErrorCode code, |
hashimoto
2012/07/10 03:48:39
Please rename |code| to more informative name, see
yoshiki
2012/07/11 00:47:14
Done.
|
+ const std::string& data) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ // This pointer of scped_ptr is to ensure a deletion of the parsed json value |
+ // object, even when OnDataParsed() is not called. |
+ scoped_ptr<base::Value>* parsed_value = new scoped_ptr<base::Value>(); |
hashimoto
2012/07/10 03:48:39
I've once tried to introduce this pointer-to-scope
yoshiki
2012/07/11 00:47:14
As I added the comment, sometimes json might be so
|
+ |
+ return BrowserThread::PostBlockingPoolTaskAndReply( |
+ FROM_HERE, |
+ base::Bind(&ParseJsonOnBlockingPool, |
+ data, |
+ parsed_value), |
+ base::Bind(&GetDataOperation::OnDataParsed, |
+ AsWeakPtr(), |
+ code, |
+ base::Owned(parsed_value))); |
+} |
+ |
+void GetDataOperation::RunCallback(GDataErrorCode code, |
hashimoto
2012/07/10 03:48:39
ditto as ParseResponse().
yoshiki
2012/07/11 00:47:14
Done.
|
+ scoped_ptr<base::Value> value) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ if (!callback_.is_null()) |
+ callback_.Run(code, value.Pass()); |
+} |
+ |
+void GetDataOperation::OnDataParsed(GDataErrorCode code, |
hashimoto
2012/07/10 03:48:39
ditto as ParseResponse().
yoshiki
2012/07/11 00:47:14
Done.
|
+ scoped_ptr<base::Value>* value) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ if (!value->get()) |
+ code = GDATA_PARSE_ERROR; |
+ |
+ // The ownership of the parsed json object is transfered to RunCallBack(), |
+ // keeping the ownership of the |value| here. |
+ RunCallback(code, value->Pass()); |
+ DCHECK(!value->get()); |
+ |
+ // |value| will be deleted after return beause it is base::Owned()'d. |
} |
//============================ GetDocumentsOperation =========================== |
@@ -859,7 +898,8 @@ bool AuthorizeAppsOperation::GetContentData(std::string* upload_content_type, |
return true; |
} |
-base::Value* AuthorizeAppsOperation::ParseResponse(const std::string& data) { |
+bool AuthorizeAppsOperation::ParseResponse(GDataErrorCode code, |
+ const std::string& data) { |
// Parse entry XML. |
XmlReader xml_reader; |
scoped_ptr<DocumentEntry> entry; |
@@ -888,7 +928,9 @@ base::Value* AuthorizeAppsOperation::ParseResponse(const std::string& data) { |
} |
} |
- return link_list.release(); |
+ RunCallback(code, link_list.PassAs<base::Value>()); |
+ |
+ return true; |
} |
GURL AuthorizeAppsOperation::GetURL() const { |