Changeset 57145 in webkit
- Timestamp:
- Apr 6, 2010 6:33:32 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r57141 r57145 1 2010-04-06 Vitaly Repeshko <vitalyr@chromium.org> 2 3 Reviewed by Yury Semikhatsky. 4 5 [V8] Extend the set of types supported by SerializedScriptValue 6 https://bugs.webkit.org/show_bug.cgi?id=37052 7 8 New types include sparse arrays, Uint32, Date, and ImageData. 9 10 Serialization process became more flexible. A state can either 11 directly write primitive values (instead of returning them like 12 iterator) or construct a new state for serializing complex values 13 that will return to the current state when done. 14 15 Deserialization process now avoids exposing the tags using a set 16 of factory functions for complex objects instead. 17 18 Internal buffer type changed to uint8_t to be independent of 19 whether char is signed or not. 20 21 * bindings/v8/SerializedScriptValue.cpp: 22 (WebCore::): 23 (WebCore::Writer::Writer): 24 (WebCore::Writer::writeString): 25 (WebCore::Writer::writeUint32): 26 (WebCore::Writer::writeDate): 27 (WebCore::Writer::writeNumber): 28 (WebCore::Writer::writeImageData): 29 (WebCore::Writer::writeArray): 30 (WebCore::Writer::writeObject): 31 (WebCore::Writer::writeSparseArray): 32 (WebCore::Writer::doWriteUint32): 33 (WebCore::Writer::doWriteNumber): 34 (WebCore::Writer::append): 35 (WebCore::Writer::fillHole): 36 (WebCore::Writer::byteAt): 37 (WebCore::Serializer::Serializer): 38 (WebCore::Serializer::serialize): 39 (WebCore::Serializer::writeArray): 40 (WebCore::Serializer::writeObject): 41 (WebCore::Serializer::writeSparseArray): 42 (WebCore::Serializer::StateBase::StateBase): 43 (WebCore::Serializer::ErrorState::ErrorState): 44 (WebCore::Serializer::ErrorState::advance): 45 (WebCore::Serializer::State::composite): 46 (WebCore::Serializer::State::State): 47 (WebCore::Serializer::ArrayState::ArrayState): 48 (WebCore::Serializer::ArrayState::advance): 49 (WebCore::Serializer::AbstractObjectState::AbstractObjectState): 50 (WebCore::Serializer::AbstractObjectState::advance): 51 (WebCore::Serializer::ObjectState::ObjectState): 52 (WebCore::Serializer::ObjectState::objectDone): 53 (WebCore::Serializer::SparseArrayState::SparseArrayState): 54 (WebCore::Serializer::SparseArrayState::objectDone): 55 (WebCore::Serializer::push): 56 (WebCore::Serializer::pop): 57 (WebCore::Serializer::handleError): 58 (WebCore::Serializer::checkComposite): 59 (WebCore::Serializer::writeString): 60 (WebCore::Serializer::writeImageData): 61 (WebCore::Serializer::newArrayState): 62 (WebCore::Serializer::newObjectState): 63 (WebCore::Serializer::doSerialize): 64 (WebCore::Reader::Reader): 65 (WebCore::Reader::read): 66 (WebCore::Reader::readString): 67 (WebCore::Reader::readUint32): 68 (WebCore::Reader::readDate): 69 (WebCore::Reader::readNumber): 70 (WebCore::Reader::readImageData): 71 (WebCore::Reader::doReadUint32): 72 (WebCore::Reader::doReadNumber): 73 (WebCore::Deserializer::Deserializer): 74 (WebCore::Deserializer::createArray): 75 (WebCore::Deserializer::createObject): 76 (WebCore::Deserializer::createSparseArray): 77 (WebCore::Deserializer::initializeObject): 78 (WebCore::Deserializer::doDeserialize): 79 (WebCore::Deserializer::stackDepth): 80 (WebCore::SerializedScriptValue::deserialize): 81 1 82 2010-04-06 Csaba Osztrogonác <ossy@webkit.org> 2 83 -
trunk/WebCore/bindings/v8/SerializedScriptValue.cpp
r57133 r57145 32 32 #include "SerializedScriptValue.h" 33 33 34 #include "ByteArray.h" 35 #include "CanvasPixelArray.h" 36 #include "ImageData.h" 34 37 #include "SharedBuffer.h" 38 #include "V8ImageData.h" 35 39 36 40 #include <v8.h> … … 41 45 // FIXME: 42 46 // - catch V8 exceptions 43 // - be ready to get empty handles44 47 // - consider crashing in debug mode on deserialization errors 45 48 … … 61 64 StringTag = 'S', 62 65 Int32Tag = 'I', 66 Uint32Tag = 'U', 67 DateTag = 'D', 63 68 NumberTag = 'N', 69 ImageDataTag = '#', 70 ArrayTag = '[', 64 71 ObjectTag = '{', 65 ArrayTag = '[',72 SparseArrayTag = '@', 66 73 }; 67 68 // Helpers to do verbose handle casts.69 70 template <typename T, typename U>71 static v8::Handle<T> handleCast(v8::Handle<U> handle) { return v8::Handle<T>::Cast(handle); }72 73 template <typename T, typename U>74 static v8::Local<T> handleCast(v8::Local<U> handle) { return v8::Local<T>::Cast(handle); }75 74 76 75 static bool shouldCheckForCycles(int depth) … … 119 118 class Writer : Noncopyable { 120 119 public: 121 Writer() : m_position(0) 120 Writer() 121 : m_position(0) 122 122 { 123 123 } … … 135 135 void writeString(const char* data, int length) 136 136 { 137 ASSERT(length >= 0); 137 138 append(StringTag); 138 139 doWriteUint32(static_cast<uint32_t>(length)); 139 append( data, length);140 append(reinterpret_cast<const uint8_t*>(data), length); 140 141 } 141 142 … … 146 147 } 147 148 149 void writeUint32(uint32_t value) 150 { 151 append(Uint32Tag); 152 doWriteUint32(value); 153 } 154 155 void writeDate(double numberValue) 156 { 157 append(DateTag); 158 doWriteNumber(numberValue); 159 } 160 148 161 void writeNumber(double number) 149 162 { 150 163 append(NumberTag); 151 append(reinterpret_cast<char*>(&number), sizeof(number)); 152 } 153 154 // Records that a composite object can be constructed by using 155 // |length| previously stored values. 156 void endComposite(SerializationTag tag, int32_t length) 157 { 158 ASSERT(tag == ObjectTag || tag == ArrayTag); 159 append(tag); 160 doWriteUint32(static_cast<uint32_t>(length)); 164 doWriteNumber(number); 165 } 166 167 void writeImageData(uint32_t width, uint32_t height, const uint8_t* pixelData, uint32_t pixelDataLength) 168 { 169 append(ImageDataTag); 170 doWriteUint32(width); 171 doWriteUint32(height); 172 doWriteUint32(pixelDataLength); 173 append(pixelData, pixelDataLength); 174 } 175 176 void writeArray(uint32_t length) 177 { 178 append(ArrayTag); 179 doWriteUint32(length); 180 } 181 182 void writeObject(uint32_t numProperties) 183 { 184 append(ObjectTag); 185 doWriteUint32(numProperties); 186 } 187 188 void writeSparseArray(uint32_t numProperties, uint32_t length) 189 { 190 append(SparseArrayTag); 191 doWriteUint32(numProperties); 192 doWriteUint32(length); 161 193 } 162 194 … … 171 203 { 172 204 while (true) { 173 charb = (value & varIntMask);205 uint8_t b = (value & varIntMask); 174 206 value >>= varIntShift; 175 207 if (!value) { … … 181 213 } 182 214 215 void doWriteNumber(double number) 216 { 217 append(reinterpret_cast<uint8_t*>(&number), sizeof(number)); 218 } 219 183 220 void append(SerializationTag tag) 184 221 { 185 append(static_cast< char>(tag));186 } 187 188 void append( charb)222 append(static_cast<uint8_t>(tag)); 223 } 224 225 void append(uint8_t b) 189 226 { 190 227 ensureSpace(1); 191 * charAt(m_position++) = b;192 } 193 194 void append(const char* data, int length)228 *byteAt(m_position++) = b; 229 } 230 231 void append(const uint8_t* data, int length) 195 232 { 196 233 ensureSpace(length); 197 memcpy( charAt(m_position), data, length);234 memcpy(byteAt(m_position), data, length); 198 235 m_position += length; 199 236 } … … 211 248 // the bytes in the last UChar is not initialized. 212 249 if (m_position % 2) 213 * charAt(m_position) = static_cast<char>(PaddingTag);214 } 215 216 char* charAt(int position) { return reinterpret_cast<char*>(m_buffer.data()) + position; }250 *byteAt(m_position) = static_cast<uint8_t>(PaddingTag); 251 } 252 253 uint8_t* byteAt(int position) { return reinterpret_cast<uint8_t*>(m_buffer.data()) + position; } 217 254 218 255 Vector<BufferValueType> m_buffer; … … 221 258 222 259 class Serializer { 260 class StateBase; 223 261 public: 224 262 explicit Serializer(Writer& writer) 225 263 : m_writer(writer) 226 , m_state(0)227 264 , m_depth(0) 265 , m_hasError(false) 228 266 { 229 267 } … … 232 270 { 233 271 v8::HandleScope scope; 234 StackCleaner cleaner(&m_state); 235 if (!doSerialize(value)) 236 return false; 237 while (top()) { 238 int length; 239 while (!top()->isDone(&length)) { 240 // Note that doSerialize() can change current top(). 241 if (!doSerialize(top()->advance())) 242 return false; 243 } 244 m_writer.endComposite(top()->tag(), length); 245 pop(); 246 } 247 return true; 272 StateBase* state = doSerialize(value, 0); 273 while (state) 274 state = state->advance(*this); 275 return !m_hasError; 276 } 277 278 // Functions used by serialization states. 279 280 StateBase* doSerialize(v8::Handle<v8::Value> value, StateBase* next); 281 282 StateBase* writeArray(uint32_t length, StateBase* state) 283 { 284 m_writer.writeArray(length); 285 return pop(state); 286 } 287 288 StateBase* writeObject(uint32_t numProperties, StateBase* state) 289 { 290 m_writer.writeObject(numProperties); 291 return pop(state); 292 } 293 294 StateBase* writeSparseArray(uint32_t numProperties, uint32_t length, StateBase* state) 295 { 296 m_writer.writeSparseArray(numProperties, length); 297 return pop(state); 248 298 } 249 299 … … 255 305 // Link to the next state to form a stack. 256 306 StateBase* nextState() { return m_next; } 257 void setNextState(StateBase* next) { m_next = next; }258 307 259 308 // Composite object we're processing in this state. 260 309 v8::Handle<v8::Value> composite() { return m_composite; } 261 310 262 // Serialization tag for the current composite. 263 virtual SerializationTag tag() const = 0; 264 265 // Returns whether iteration over subobjects of the current 266 // composite object is done. If yes, |*length| is set to the 267 // number of subobjects. 268 virtual bool isDone(int* length) = 0; 269 270 // Advances to the next subobject. 271 // Requires: !this->isDone(). 272 virtual v8::Local<v8::Value> advance() = 0; 311 // Serializes (a part of) the current composite and returns 312 // the next state to process or null when this is the final 313 // state. 314 virtual StateBase* advance(Serializer&) = 0; 273 315 274 316 protected: 275 StateBase(v8::Handle<v8::Value> composite )276 : m_ next(0)277 , m_ composite(composite)317 StateBase(v8::Handle<v8::Value> composite, StateBase* next) 318 : m_composite(composite) 319 , m_next(next) 278 320 { 279 321 } 280 322 281 323 private: 324 v8::Handle<v8::Value> m_composite; 282 325 StateBase* m_next; 283 v8::Handle<v8::Value> m_composite;284 326 }; 285 327 286 template <typename T, SerializationTag compositeTag> 328 // Dummy state that is used to signal serialization errors. 329 class ErrorState : public StateBase { 330 public: 331 ErrorState() 332 : StateBase(v8::Handle<v8::Value>(), 0) 333 { 334 } 335 336 virtual StateBase* advance(Serializer&) 337 { 338 delete this; 339 return 0; 340 } 341 }; 342 343 template <typename T> 287 344 class State : public StateBase { 288 345 public: 289 v8::Handle<T> composite() { return handleCast<T>(StateBase::composite()); } 290 291 virtual SerializationTag tag() const { return compositeTag; } 346 v8::Handle<T> composite() { return v8::Handle<T>::Cast(StateBase::composite()); } 292 347 293 348 protected: 294 explicit State(v8::Handle<T> composite) : StateBase(composite) 349 State(v8::Handle<T> composite, StateBase* next) 350 : StateBase(composite, next) 295 351 { 296 352 } 297 353 }; 298 354 299 // Helper to clean up the state stack in case of errors. 300 class StackCleaner : Noncopyable { 355 #if 0 356 // Currently unused, see comment in newArrayState. 357 class ArrayState : public State<v8::Array> { 301 358 public: 302 explicit StackCleaner(StateBase** stack) : m_stack(stack) 303 { 304 } 305 306 ~StackCleaner() 307 { 308 StateBase* state = *m_stack; 309 while (state) { 310 StateBase* tmp = state->nextState(); 311 delete state; 312 state = tmp; 359 ArrayState(v8::Handle<v8::Array> array, StateBase* next) 360 : State<v8::Array>(array, next) 361 , m_index(-1) 362 { 363 } 364 365 virtual StateBase* advance(Serializer& serializer) 366 { 367 ++m_index; 368 for (; m_index < composite()->Length(); ++m_index) { 369 if (StateBase* newState = serializer.doSerialize(composite()->Get(m_index), this)) 370 return newState; 313 371 } 314 *m_stack = 0; 315 } 316 317 private: 318 StateBase** m_stack; 319 }; 320 321 class ArrayState : public State<v8::Array, ArrayTag> { 322 public: 323 ArrayState(v8::Handle<v8::Array> array) 324 : State<v8::Array, ArrayTag>(array) 325 , m_index(0) 326 { 327 } 328 329 virtual bool isDone(int* length) 330 { 331 *length = composite()->Length(); 332 return static_cast<int>(m_index) >= *length; 333 } 334 335 virtual v8::Local<v8::Value> advance() 336 { 337 ASSERT(m_index < composite()->Length()); 338 v8::HandleScope scope; 339 return scope.Close(composite()->Get(v8::Integer::New(m_index++))); 372 return serializer.writeArray(composite()->Length(), this); 340 373 } 341 374 … … 343 376 unsigned m_index; 344 377 }; 345 346 class ObjectState : public State<v8::Object, ObjectTag> { 378 #endif 379 380 class AbstractObjectState : public State<v8::Object> { 347 381 public: 348 ObjectState(v8::Handle<v8::Object> object)349 : State<v8::Object , ObjectTag>(object)382 AbstractObjectState(v8::Handle<v8::Object> object, StateBase* next) 383 : State<v8::Object>(object, next) 350 384 , m_propertyNames(object->GetPropertyNames()) 351 385 , m_index(-1) 352 , m_length(0) 353 { 354 nextProperty(); 355 } 356 357 virtual bool isDone(int* length) 358 { 359 *length = m_length; 360 return m_index >= 2 * m_propertyNames->Length(); 361 } 362 363 virtual v8::Local<v8::Value> advance() 364 { 365 ASSERT(m_index < 2 * m_propertyNames->Length()); 366 if (!(m_index % 2)) { 367 ++m_index; 368 return m_propertyName; 386 , m_nameDone(false) 387 { 388 } 389 390 virtual StateBase* advance(Serializer& serializer) 391 { 392 ++m_index; 393 for (; m_index < m_propertyNames->Length(); ++m_index) { 394 if (m_propertyName.IsEmpty()) { 395 v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_index); 396 if ((propertyName->IsString() && composite()->HasRealNamedProperty(propertyName.As<v8::String>())) 397 || (propertyName->IsUint32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value()))) { 398 m_propertyName = propertyName; 399 } else 400 continue; 401 } 402 ASSERT(!m_propertyName.IsEmpty()); 403 if (!m_nameDone) { 404 m_nameDone = true; 405 if (StateBase* newState = serializer.doSerialize(m_propertyName, this)) 406 return newState; 407 } 408 v8::Local<v8::Value> value = composite()->Get(m_propertyName); 409 m_nameDone = false; 410 m_propertyName.Clear(); 411 if (StateBase* newState = serializer.doSerialize(value, this)) 412 return newState; 369 413 } 370 v8::Local<v8::Value> result = composite()->Get(m_propertyName); 371 nextProperty(); 372 return result; 373 } 414 return objectDone(m_index, serializer); 415 } 416 417 protected: 418 virtual StateBase* objectDone(unsigned numProperties, Serializer&) = 0; 374 419 375 420 private: 376 void nextProperty()377 {378 v8::HandleScope scope;379 ++m_index;380 ASSERT(!(m_index % 2));381 for (; m_index < 2 * m_propertyNames->Length(); m_index += 2) {382 v8::Local<v8::Value> propertyName = m_propertyNames->Get(v8::Integer::New(m_index / 2));383 if ((propertyName->IsString() && composite()->HasRealNamedProperty(handleCast<v8::String>(propertyName)))384 || (propertyName->IsInt32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value()))) {385 m_propertyName = scope.Close(propertyName);386 m_length += 2;387 return;388 }389 }390 }391 392 421 v8::Local<v8::Array> m_propertyNames; 393 422 v8::Local<v8::Value> m_propertyName; 394 423 unsigned m_index; 395 unsigned m_length;424 bool m_nameDone; 396 425 }; 397 426 398 bool doSerialize(v8::Handle<v8::Value> value) 399 { 400 if (value->IsUndefined()) 401 m_writer.writeUndefined(); 402 else if (value->IsNull()) 403 m_writer.writeNull(); 404 else if (value->IsTrue()) 405 m_writer.writeTrue(); 406 else if (value->IsFalse()) 407 m_writer.writeFalse(); 408 else if (value->IsInt32()) 409 m_writer.writeInt32(value->Int32Value()); 410 else if (value->IsNumber()) 411 m_writer.writeNumber(handleCast<v8::Number>(value)->Value()); 412 else if (value->IsString()) { 413 v8::String::Utf8Value stringValue(value); 414 m_writer.writeString(*stringValue, stringValue.length()); 415 } else if (value->IsArray()) { 416 if (!checkComposite(value)) 417 return false; 418 push(new ArrayState(handleCast<v8::Array>(value))); 419 } else if (value->IsObject()) { 420 if (!checkComposite(value)) 421 return false; 422 push(new ObjectState(handleCast<v8::Object>(value))); 423 // FIXME: 424 // - check not a wrapper 425 // - support File, ImageData, etc. 426 } 427 return true; 428 } 429 430 void push(StateBase* state) 431 { 432 state->setNextState(m_state); 433 m_state = state; 427 class ObjectState : public AbstractObjectState { 428 public: 429 ObjectState(v8::Handle<v8::Object> object, StateBase* next) 430 : AbstractObjectState(object, next) 431 { 432 } 433 434 protected: 435 virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) 436 { 437 return serializer.writeObject(numProperties, this); 438 } 439 }; 440 441 class SparseArrayState : public AbstractObjectState { 442 public: 443 SparseArrayState(v8::Handle<v8::Array> array, StateBase* next) 444 : AbstractObjectState(array, next) 445 { 446 } 447 448 protected: 449 virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) 450 { 451 return serializer.writeSparseArray(numProperties, composite().As<v8::Array>()->Length(), this); 452 } 453 }; 454 455 StateBase* push(StateBase* state) 456 { 457 ASSERT(state); 434 458 ++m_depth; 435 } 436 437 StateBase* top() { return m_state; } 438 439 void pop() 440 { 441 if (!m_state) 442 return; 443 StateBase* top = m_state; 444 m_state = top->nextState(); 445 delete top; 459 return checkComposite(state) ? state : handleError(state); 460 } 461 462 StateBase* pop(StateBase* state) 463 { 464 ASSERT(state); 446 465 --m_depth; 447 } 448 449 bool checkComposite(v8::Handle<v8::Value> composite) 450 { 466 StateBase* next = state->nextState(); 467 delete state; 468 return next; 469 } 470 471 StateBase* handleError(StateBase* state) 472 { 473 m_hasError = true; 474 while (state) { 475 StateBase* tmp = state->nextState(); 476 delete state; 477 state = tmp; 478 } 479 return new ErrorState; 480 } 481 482 bool checkComposite(StateBase* top) 483 { 484 ASSERT(top); 451 485 if (m_depth > maxDepth) 452 486 return false; 453 487 if (!shouldCheckForCycles(m_depth)) 454 488 return true; 455 for (StateBase* state = top(); state; state = state->nextState()) { 489 v8::Handle<v8::Value> composite = top->composite(); 490 for (StateBase* state = top->nextState(); state; state = state->nextState()) { 456 491 if (state->composite() == composite) 457 492 return false; … … 460 495 } 461 496 497 void writeString(v8::Handle<v8::Value> value) 498 { 499 v8::String::Utf8Value stringValue(value); 500 m_writer.writeString(*stringValue, stringValue.length()); 501 } 502 503 void writeImageData(v8::Handle<v8::Value> value) 504 { 505 ImageData* imageData = V8ImageData::toNative(value.As<v8::Object>()); 506 if (!imageData) 507 return; 508 WTF::ByteArray* pixelArray = imageData->data()->data(); 509 m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray->data(), pixelArray->length()); 510 } 511 512 static StateBase* newArrayState(v8::Handle<v8::Array> array, StateBase* next) 513 { 514 // FIXME: use plain Array state when we can quickly check that 515 // an array is not sparse and has only indexed properties. 516 return new SparseArrayState(array, next); 517 } 518 519 static StateBase* newObjectState(v8::Handle<v8::Object> object, StateBase* next) 520 { 521 // FIXME: 522 // - check not a wrapper 523 // - support File, etc. 524 return new ObjectState(object, next); 525 } 526 462 527 Writer& m_writer; 463 StateBase* m_state;464 528 int m_depth; 529 bool m_hasError; 530 }; 531 532 Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, StateBase* next) 533 { 534 if (value->IsUndefined()) 535 m_writer.writeUndefined(); 536 else if (value->IsNull()) 537 m_writer.writeNull(); 538 else if (value->IsTrue()) 539 m_writer.writeTrue(); 540 else if (value->IsFalse()) 541 m_writer.writeFalse(); 542 else if (value->IsInt32()) 543 m_writer.writeInt32(value->Int32Value()); 544 else if (value->IsUint32()) 545 m_writer.writeUint32(value->Uint32Value()); 546 else if (value->IsDate()) 547 m_writer.writeDate(value->NumberValue()); 548 else if (value->IsNumber()) 549 m_writer.writeNumber(value.As<v8::Number>()->Value()); 550 else if (value->IsString()) 551 writeString(value); 552 else if (value->IsArray()) 553 return push(newArrayState(value.As<v8::Array>(), next)); 554 else if (V8ImageData::HasInstance(value)) 555 writeImageData(value); 556 else if (value->IsObject()) 557 return push(newObjectState(value.As<v8::Object>(), next)); 558 return 0; 559 } 560 561 // Interface used by Reader to create objects of composite types. 562 class CompositeCreator { 563 public: 564 virtual ~CompositeCreator() { } 565 566 virtual bool createArray(uint32_t length, v8::Handle<v8::Value>* value) = 0; 567 virtual bool createObject(uint32_t numProperties, v8::Handle<v8::Value>* value) = 0; 568 virtual bool createSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) = 0; 465 569 }; 466 570 … … 469 573 class Reader { 470 574 public: 471 Reader(const char* buffer, int length)575 Reader(const uint8_t* buffer, int length) 472 576 : m_buffer(buffer) 473 577 , m_length(length) … … 479 583 bool isEof() const { return m_position >= m_length; } 480 584 481 bool read( SerializationTag* tag, v8::Handle<v8::Value>* value, int* length)482 { 483 uint32_t rawLength;484 if (!readTag( tag))485 return false; 486 switch ( *tag) {585 bool read(v8::Handle<v8::Value>* value, CompositeCreator& creator) 586 { 587 SerializationTag tag; 588 if (!readTag(&tag)) 589 return false; 590 switch (tag) { 487 591 case InvalidTag: 488 592 return false; 489 593 case PaddingTag: 490 break;594 return true; 491 595 case UndefinedTag: 492 596 *value = v8::Undefined(); … … 509 613 return false; 510 614 break; 615 case Uint32Tag: 616 if (!readUint32(value)) 617 return false; 618 break; 619 case DateTag: 620 if (!readDate(value)) 621 return false; 622 break; 511 623 case NumberTag: 512 624 if (!readNumber(value)) 513 625 return false; 514 626 break; 515 case ObjectTag: 516 case ArrayTag: 517 if (!doReadUint32(&rawLength)) 518 return false; 519 *length = rawLength; 520 break; 521 } 522 return true; 627 case ImageDataTag: 628 if (!readImageData(value)) 629 return false; 630 break; 631 case ArrayTag: { 632 uint32_t length; 633 if (!doReadUint32(&length)) 634 return false; 635 if (!creator.createArray(length, value)) 636 return false; 637 break; 638 } 639 case ObjectTag: { 640 uint32_t numProperties; 641 if (!doReadUint32(&numProperties)) 642 return false; 643 if (!creator.createObject(numProperties, value)) 644 return false; 645 break; 646 } 647 case SparseArrayTag: { 648 uint32_t numProperties; 649 uint32_t length; 650 if (!doReadUint32(&numProperties)) 651 return false; 652 if (!doReadUint32(&length)) 653 return false; 654 if (!creator.createSparseArray(numProperties, length, value)) 655 return false; 656 break; 657 } 658 default: 659 return false; 660 } 661 return !value->IsEmpty(); 523 662 } 524 663 … … 539 678 if (m_position + length > m_length) 540 679 return false; 541 *value = v8::String::New( m_buffer + m_position, length);680 *value = v8::String::New(reinterpret_cast<const char*>(m_buffer + m_position), length); 542 681 m_position += length; 543 682 return true; … … 553 692 } 554 693 694 bool readUint32(v8::Handle<v8::Value>* value) 695 { 696 uint32_t rawValue; 697 if (!doReadUint32(&rawValue)) 698 return false; 699 *value = v8::Integer::New(rawValue); 700 return true; 701 } 702 703 bool readDate(v8::Handle<v8::Value>* value) 704 { 705 double numberValue; 706 if (!doReadNumber(&numberValue)) 707 return false; 708 *value = v8::Date::New(numberValue); 709 return true; 710 } 711 555 712 bool readNumber(v8::Handle<v8::Value>* value) 556 713 { 557 if (m_position + sizeof(double) > m_length)558 return false;559 714 double number; 560 char* numberAsByteArray = reinterpret_cast<char*>(&number); 561 for (unsigned i = 0; i < sizeof(double); ++i) 562 numberAsByteArray[i] = m_buffer[m_position++]; 715 if (!doReadNumber(&number)) 716 return false; 563 717 *value = v8::Number::New(number); 564 718 return true; 565 719 } 566 720 721 bool readImageData(v8::Handle<v8::Value>* value) 722 { 723 uint32_t width; 724 uint32_t height; 725 uint32_t pixelDataLength; 726 if (!doReadUint32(&width)) 727 return false; 728 if (!doReadUint32(&height)) 729 return false; 730 if (!doReadUint32(&pixelDataLength)) 731 return false; 732 if (m_position + pixelDataLength > m_length) 733 return false; 734 PassRefPtr<ImageData> imageData = ImageData::create(width, height); 735 WTF::ByteArray* pixelArray = imageData->data()->data(); 736 ASSERT(pixelArray); 737 ASSERT(pixelArray->length() >= pixelDataLength); 738 memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength); 739 m_position += pixelDataLength; 740 *value = toV8(imageData); 741 return true; 742 } 743 567 744 bool doReadUint32(uint32_t* value) 568 745 { 569 746 *value = 0; 570 charcurrentByte;747 uint8_t currentByte; 571 748 int shift = 0; 572 749 do { … … 580 757 } 581 758 582 const char* m_buffer; 759 bool doReadNumber(double* number) 760 { 761 if (m_position + sizeof(double) > m_length) 762 return false; 763 uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number); 764 for (unsigned i = 0; i < sizeof(double); ++i) 765 numberAsByteArray[i] = m_buffer[m_position++]; 766 return true; 767 } 768 769 const uint8_t* m_buffer; 583 770 const unsigned m_length; 584 771 unsigned m_position; 585 772 }; 586 773 587 class Deserializer {774 class Deserializer : public CompositeCreator { 588 775 public: 589 explicit Deserializer(Reader& reader) : m_reader(reader) 776 explicit Deserializer(Reader& reader) 777 : m_reader(reader) 590 778 { 591 779 } … … 603 791 } 604 792 793 virtual bool createArray(uint32_t length, v8::Handle<v8::Value>* value) 794 { 795 if (length > stackDepth()) 796 return false; 797 v8::Local<v8::Array> array = v8::Array::New(length); 798 if (array.IsEmpty()) 799 return false; 800 const int depth = stackDepth() - length; 801 for (unsigned i = 0; i < length; ++i) 802 array->Set(i, element(depth + i)); 803 pop(length); 804 *value = array; 805 return true; 806 } 807 808 virtual bool createObject(uint32_t numProperties, v8::Handle<v8::Value>* value) 809 { 810 v8::Local<v8::Object> object = v8::Object::New(); 811 if (object.IsEmpty()) 812 return false; 813 return initializeObject(object, numProperties, value); 814 } 815 816 virtual bool createSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) 817 { 818 v8::Local<v8::Array> array = v8::Array::New(length); 819 if (array.IsEmpty()) 820 return false; 821 return initializeObject(array, numProperties, value); 822 } 823 605 824 private: 825 bool initializeObject(v8::Handle<v8::Object> object, uint32_t numProperties, v8::Handle<v8::Value>* value) 826 { 827 unsigned length = 2 * numProperties; 828 if (length > stackDepth()) 829 return false; 830 for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) { 831 v8::Local<v8::Value> propertyName = element(i); 832 v8::Local<v8::Value> propertyValue = element(i + 1); 833 object->Set(propertyName, propertyValue); 834 } 835 pop(length); 836 *value = object; 837 return true; 838 } 839 606 840 bool doDeserialize() 607 841 { 608 SerializationTag tag;609 842 v8::Local<v8::Value> value; 610 int length = 0; 611 if (!m_reader.read(&tag, &value, &length)) 612 return false; 613 if (!value.IsEmpty()) { 843 if (!m_reader.read(&value, *this)) 844 return false; 845 if (!value.IsEmpty()) 614 846 push(value); 615 } else if (tag == ObjectTag) {616 if (length > stackDepth())617 return false;618 v8::Local<v8::Object> object = v8::Object::New();619 for (int i = stackDepth() - length; i < stackDepth(); i += 2) {620 v8::Local<v8::Value> propertyName = element(i);621 v8::Local<v8::Value> propertyValue = element(i + 1);622 object->Set(propertyName, propertyValue);623 }624 pop(length);625 push(object);626 } else if (tag == ArrayTag) {627 if (length > stackDepth())628 return false;629 v8::Local<v8::Array> array = v8::Array::New(length);630 const int depth = stackDepth() - length;631 {632 v8::HandleScope scope;633 for (int i = 0; i < length; ++i)634 array->Set(v8::Integer::New(i), element(depth + i));635 }636 pop(length);637 push(array);638 } else if (tag != PaddingTag)639 return false;640 847 return true; 641 848 } … … 649 856 } 650 857 651 intstackDepth() const { return m_stack.size(); }858 unsigned stackDepth() const { return m_stack.size(); } 652 859 653 860 v8::Local<v8::Value> element(unsigned index) … … 692 899 return v8::Null(); 693 900 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); 694 Reader reader(reinterpret_cast<const char*>(m_data.impl()->characters()), 2 * m_data.length());901 Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters()), 2 * m_data.length()); 695 902 Deserializer deserializer(reader); 696 903 return deserializer.deserialize();
Note: See TracChangeset
for help on using the changeset viewer.