Hello michaeln,
I'd like you to do a code review. Please execute
g4 diff -c 10579925
or point your web browser to
http://mondrian/10579925
to review the following code:
Change 10579925 by nigel...@nigeltao-srcgears5 on 2009/03/24 14:22:49 *pending*
BlobBuilder.append (the JS API, not the C++ API) now takes
an int or an array, not just a (UTF-8) string or a blob.
PRESUBMIT=passed
R=michaeln
[email protected]
DELTA=172 (136 added, 15 deleted, 21 changed)
OCL=10579925
Affected files ...
... //depot/googleclient/gears/opensource/gears/base/common/js_types.h#41 edit
... //depot/googleclient/gears/opensource/gears/blob/blob_builder_module.cc#2
edit
... //depot/googleclient/gears/opensource/gears/blob/blob_builder_module.h#1
edit
... //depot/googleclient/gears/opensource/gears/test/testcases/blob_tests.js#3
edit
172 delta lines: 136 added, 15 deleted, 21 changed
Also consider running:
g4 lint -c 10579925
which verifies that the changelist doesn't introduce new style violations.
If you can't do the review, please let me know as soon as possible. During
your review, please ensure that all new code has corresponding unit tests and
that existing unit tests are updated appropriately. Visit
http://www/eng/code_review.html for more information.
This is a semiautomated message from "g4 mail". Complaints or suggestions?
Mail [email protected].
Change 10579925 by nigel...@nigeltao-srcgears5 on 2009/03/24 14:22:49 *pending*
BlobBuilder.append (the JS API, not the C++ API) now takes
an int or an array, not just a (UTF-8) string or a blob.
Affected files ...
... //depot/googleclient/gears/opensource/gears/base/common/js_types.h#41 edit
... //depot/googleclient/gears/opensource/gears/blob/blob_builder_module.cc#2
edit
... //depot/googleclient/gears/opensource/gears/blob/blob_builder_module.h#1
edit
... //depot/googleclient/gears/opensource/gears/test/testcases/blob_tests.js#3
edit
==== //depot/googleclient/gears/opensource/gears/base/common/js_types.h#41 -
/home/nigeltao/srcgears5/googleclient/gears/opensource/gears/base/common/js_types.h
====
# action=edit type=text
--- googleclient/gears/opensource/gears/base/common/js_types.h 2009-03-24
14:15:40.000000000 +1100
+++ googleclient/gears/opensource/gears/base/common/js_types.h 2009-03-23
16:03:11.000000000 +1100
@@ -546,9 +546,9 @@
JsRunnerInterface *js_runner() { return js_runner_; }
#endif
+ const JsToken &GetArgument(int index);
+
private:
- const JsToken &GetArgument(int index);
-
JsContextPtr js_context_;
bool is_exception_set_;
bool is_return_value_set_;
==== //depot/googleclient/gears/opensource/gears/blob/blob_builder_module.cc#2
-
/home/nigeltao/srcgears5/googleclient/gears/opensource/gears/blob/blob_builder_module.cc
====
# action=edit type=text
--- googleclient/gears/opensource/gears/blob/blob_builder_module.cc
2009-03-24 14:15:41.000000000 +1100
+++ googleclient/gears/opensource/gears/blob/blob_builder_module.cc
2009-03-24 14:07:58.000000000 +1100
@@ -50,45 +50,97 @@
}
-void GearsBlobBuilder::Append(JsCallContext *context) {
- int appendee_type = context->GetArgumentType(0);
-
- std::string16 appendee_as_string;
- ModuleImplBaseClass *appendee_as_module = NULL;
- JsArgument argv[] = {
- { JSPARAM_REQUIRED, JSPARAM_UNKNOWN, NULL },
- };
- if (appendee_type == JSPARAM_STRING16) {
- argv[0].type = JSPARAM_STRING16;
- argv[0].value_ptr = &appendee_as_string;
- } else {
- // We set argv[0].type to ask for a JSPARAM_MODULE. If the first argument
- // was neither a string nor a Gears module, then the context->GetArguments
- // call a few lines down will fail.
- argv[0].type = JSPARAM_MODULE;
- argv[0].value_ptr = &appendee_as_module;
+bool GearsBlobBuilder::Append(
+ const JsToken &token,
+ JsContextPtr js_context,
+ AbstractJsTokenVector *array_stack) {
+ if (array_stack != NULL) {
+ AbstractJsToken abstract_js_token = JsTokenPtrToAbstractJsToken(
+ const_cast<JsToken*>(&token));
+ for (AbstractJsTokenVector::iterator iter = array_stack->begin();
+ iter != array_stack->end();
+ ++iter) {
+ if (module_environment_->js_runner_->
+ AbstractJsTokensAreEqual(abstract_js_token, *iter)) {
+ return false;
+ }
+ }
}
- if (!context->GetArguments(ARRAYSIZE(argv), argv)) {
- assert(context->is_exception_set());
+ int type = JsTokenGetType(token, js_context);
+ if (type == JSPARAM_INT) {
+ int token_as_int;
+ if (!JsTokenToInt_NoCoerce(token, js_context, &token_as_int)) {
+ return false;
+ }
+ uint8 byte = static_cast<uint8>(token_as_int);
+ builder_->AddData(&byte, 1);
+ return true;
+
+ } else if (type == JSPARAM_STRING16) {
+ std::string16 token_as_string;
+ if (!JsTokenToString_NoCoerce(token, js_context, &token_as_string)) {
+ return false;
+ }
+ builder_->AddString(token_as_string);
+ return true;
+
+ } else if (type == JSPARAM_OBJECT) {
+ ModuleImplBaseClass *token_as_module = NULL;
+ if (!JsTokenToModule(module_environment_->js_runner_,
+ js_context, token, &token_as_module) ||
+ GearsBlob::kModuleName != token_as_module->get_module_name()) {
+ return false;
+ }
+ scoped_refptr<BlobInterface> blob_interface;
+ static_cast<GearsBlob*>(token_as_module)->GetContents(&blob_interface);
+ builder_->AddBlob(blob_interface.get());
+ return true;
+
+ } else if (type == JSPARAM_ARRAY) {
+ scoped_ptr<JsArray> token_as_array;
+ int array_length;
+ if (!JsTokenToArray_NoCoerce(
+ token, js_context, as_out_parameter(token_as_array)) ||
+ !token_as_array.get() ||
+ !token_as_array->GetLength(&array_length)) {
+ return false;
+ }
+ scoped_ptr<AbstractJsTokenVector> scoped_array_stack;
+ if (array_stack == NULL) {
+ scoped_array_stack.reset(new AbstractJsTokenVector);
+ array_stack = scoped_array_stack.get();
+ }
+ array_stack->push_back(JsTokenPtrToAbstractJsToken(
+ const_cast<JsToken*>(&token)));
+ for (int i = 0; i < array_length; i++) {
+ JsScopedToken array_element;
+ if (!token_as_array->GetElement(i, &array_element) ||
+ !Append(array_element, js_context, array_stack)) {
+ return false;
+ }
+ }
+ array_stack->pop_back();
+ return true;
+
+ }
+ return false;
+}
+
+
+void GearsBlobBuilder::Append(JsCallContext *context) {
+ int argc = context->GetArgumentCount();
+ if (argc != 1) {
+ context->SetException(STRING16(argc > 1
+ ? L"Too many parameters."
+ : L"Required argument 1 is missing."));
return;
}
-
- if (appendee_type == JSPARAM_STRING16) {
- builder_->AddString(appendee_as_string);
+ if (!Append(context->GetArgument(0), context->js_context(), NULL)) {
+ context->SetException(
+ STRING16(L"Parameter must be an int, string, Blob or array of such."));
return;
}
-
- if (appendee_as_module &&
- GearsBlob::kModuleName != appendee_as_module->get_module_name()) {
- context->SetException(
- STRING16(L"First parameter must be a Blob or a string."));
- return;
- }
-
- scoped_refptr<BlobInterface> blob_interface;
- static_cast<GearsBlob*>(appendee_as_module)->GetContents(&blob_interface);
- builder_->AddBlob(blob_interface.get());
}
==== //depot/googleclient/gears/opensource/gears/blob/blob_builder_module.h#1 -
/home/nigeltao/srcgears5/googleclient/gears/opensource/gears/blob/blob_builder_module.h
====
# action=edit type=text
--- googleclient/gears/opensource/gears/blob/blob_builder_module.h
2009-03-24 14:15:41.000000000 +1100
+++ googleclient/gears/opensource/gears/blob/blob_builder_module.h
2009-03-24 11:34:21.000000000 +1100
@@ -38,7 +38,7 @@
GearsBlobBuilder();
~GearsBlobBuilder();
- // IN: string|GearsBlob appendee
+ // IN: int|string|GearsBlob|array appendee
// OUT: -
void Append(JsCallContext *context);
@@ -49,6 +49,11 @@
private:
scoped_ptr<BlobBuilder> builder_;
+ bool Append(
+ const JsToken &token,
+ JsContextPtr js_context,
+ AbstractJsTokenVector *array_stack);
+
DISALLOW_EVIL_CONSTRUCTORS(GearsBlobBuilder);
};
==== //depot/googleclient/gears/opensource/gears/test/testcases/blob_tests.js#3
-
/home/nigeltao/srcgears5/googleclient/gears/opensource/gears/test/testcases/blob_tests.js
====
# action=edit type=text
--- googleclient/gears/opensource/gears/test/testcases/blob_tests.js
2009-03-24 14:15:42.000000000 +1100
+++ googleclient/gears/opensource/gears/test/testcases/blob_tests.js
2009-03-24 14:18:56.000000000 +1100
@@ -106,3 +106,67 @@
assert(bytes6a[i] == bytes6b[i]);
}
}
+
+function testBlobBuilderAppendIntStringBlobArray() {
+ // The integer values below map to ASCII characters like so:
+ // A=65, B=66, C=67, D=68, E=69, F=70, G=71, H=72, I=73, J=74, ...,
+ // W=87, X=88, Y=89, Z=90. Note that the second blob ends with 250,
+ // which is outside the range of ASCII (i.e. it is not a valid UTF-8 string
+ // and therefore not equivalent to any builder.append(string) call).
+ var builderAbcd = google.gears.factory.create('beta.blobbuilder');
+ builderAbcd.append('AB');
+ builderAbcd.append(67);
+ builderAbcd.append(68 + 2560);
+ var blobAbcd = builderAbcd.getAsBlob();
+ var bytesAbcd = blobAbcd.getBytes();
+ assertEqual(4, blobAbcd.length);
+ assertEqual(65, bytesAbcd[0]);
+ assertEqual(66, bytesAbcd[1]);
+ assertEqual(67, bytesAbcd[2]);
+ assertEqual(68, bytesAbcd[3]);
+
+ var builder = google.gears.factory.create('beta.blobbuilder');
+ builder.append('W');
+ builder.append('X');
+ builder.append([
+ 89,
+ 'Z',
+ blobAbcd,
+ [bytesAbcd, 69, 'FG', 72]
+ ]);
+ builder.append('I');
+ builder.append(250);
+ var blob = builder.getAsBlob();
+ var bytes = blob.getBytes();
+ assertEqual(18, blob.length);
+
+ assertEqual(87, bytes[0]);
+ assertEqual(88, bytes[1]);
+ assertEqual(89, bytes[2]);
+ assertEqual(90, bytes[3]);
+ assertEqual(65, bytes[4]);
+ assertEqual(66, bytes[5]);
+ assertEqual(67, bytes[6]);
+ assertEqual(68, bytes[7]);
+ assertEqual(65, bytes[8]);
+ assertEqual(66, bytes[9]);
+ assertEqual(67, bytes[10]);
+ assertEqual(68, bytes[11]);
+ assertEqual(69, bytes[12]);
+ assertEqual(70, bytes[13]);
+ assertEqual(71, bytes[14]);
+ assertEqual(72, bytes[15]);
+ assertEqual(73, bytes[16]);
+ assertEqual(250, bytes[17]);
+}
+
+function testBlobBuilderAppendRecursiveArray() {
+ var a = [1, 2];
+ var b = [3, 4, a];
+ a.push(b);
+ var builder = google.gears.factory.create('beta.blobbuilder');
+ assertError(function() {
+ // The next line should not infinite-loop.
+ builder.append(a);
+ });
+}