1 :
2 : /*
3 : * Copyright 2006 The Android Open Source Project
4 : *
5 : * Use of this source code is governed by a BSD-style license that can be
6 : * found in the LICENSE file.
7 : */
8 :
9 :
10 : #include "SkStream.h"
11 : #include "SkData.h"
12 : #include "SkFixed.h"
13 : #include "SkString.h"
14 : #include "SkOSFile.h"
15 :
16 0 : SkStream::~SkStream() {}
17 :
18 0 : const char* SkStream::getFileName()
19 : {
20 : // override in subclass if you represent a file
21 0 : return NULL;
22 : }
23 :
24 0 : const void* SkStream::getMemoryBase()
25 : {
26 : // override in subclass if you represent a memory block
27 0 : return NULL;
28 : }
29 :
30 0 : size_t SkStream::skip(size_t size)
31 : {
32 : /* Check for size == 0, and just return 0. If we passed that
33 : to read(), it would interpret it as a request for the entire
34 : size of the stream.
35 : */
36 0 : return size ? this->read(NULL, size) : 0;
37 : }
38 :
39 0 : int8_t SkStream::readS8() {
40 : int8_t value;
41 0 : SkDEBUGCODE(size_t len =) this->read(&value, 1);
42 0 : SkASSERT(1 == len);
43 0 : return value;
44 : }
45 :
46 0 : int16_t SkStream::readS16() {
47 : int16_t value;
48 0 : SkDEBUGCODE(size_t len =) this->read(&value, 2);
49 0 : SkASSERT(2 == len);
50 0 : return value;
51 : }
52 :
53 0 : int32_t SkStream::readS32() {
54 : int32_t value;
55 0 : SkDEBUGCODE(size_t len =) this->read(&value, 4);
56 0 : SkASSERT(4 == len);
57 0 : return value;
58 : }
59 :
60 0 : SkScalar SkStream::readScalar() {
61 : SkScalar value;
62 0 : SkDEBUGCODE(size_t len =) this->read(&value, sizeof(SkScalar));
63 0 : SkASSERT(sizeof(SkScalar) == len);
64 0 : return value;
65 : }
66 :
67 : #define SK_MAX_BYTE_FOR_U8 0xFD
68 : #define SK_BYTE_SENTINEL_FOR_U16 0xFE
69 : #define SK_BYTE_SENTINEL_FOR_U32 0xFF
70 :
71 0 : size_t SkStream::readPackedUInt() {
72 : uint8_t byte;
73 0 : if (!this->read(&byte, 1)) {
74 0 : return 0;
75 : }
76 0 : if (SK_BYTE_SENTINEL_FOR_U16 == byte) {
77 0 : return this->readU16();
78 0 : } else if (SK_BYTE_SENTINEL_FOR_U32 == byte) {
79 0 : return this->readU32();
80 : } else {
81 0 : return byte;
82 : }
83 : }
84 :
85 : //////////////////////////////////////////////////////////////////////////////////////
86 :
87 0 : SkWStream::~SkWStream()
88 : {
89 0 : }
90 :
91 0 : void SkWStream::newline()
92 : {
93 0 : this->write("\n", 1);
94 0 : }
95 :
96 0 : void SkWStream::flush()
97 : {
98 0 : }
99 :
100 0 : bool SkWStream::writeText(const char text[])
101 : {
102 0 : SkASSERT(text);
103 0 : return this->write(text, strlen(text));
104 : }
105 :
106 0 : bool SkWStream::writeDecAsText(int32_t dec)
107 : {
108 0 : SkString tmp;
109 0 : tmp.appendS32(dec);
110 0 : return this->write(tmp.c_str(), tmp.size());
111 : }
112 :
113 0 : bool SkWStream::writeBigDecAsText(int64_t dec, int minDigits)
114 : {
115 0 : SkString tmp;
116 0 : tmp.appendS64(dec, minDigits);
117 0 : return this->write(tmp.c_str(), tmp.size());
118 : }
119 :
120 0 : bool SkWStream::writeHexAsText(uint32_t hex, int digits)
121 : {
122 0 : SkString tmp;
123 0 : tmp.appendHex(hex, digits);
124 0 : return this->write(tmp.c_str(), tmp.size());
125 : }
126 :
127 0 : bool SkWStream::writeScalarAsText(SkScalar value)
128 : {
129 0 : SkString tmp;
130 0 : tmp.appendScalar(value);
131 0 : return this->write(tmp.c_str(), tmp.size());
132 : }
133 :
134 0 : bool SkWStream::write8(U8CPU value) {
135 0 : uint8_t v = SkToU8(value);
136 0 : return this->write(&v, 1);
137 : }
138 :
139 0 : bool SkWStream::write16(U16CPU value) {
140 0 : uint16_t v = SkToU16(value);
141 0 : return this->write(&v, 2);
142 : }
143 :
144 0 : bool SkWStream::write32(uint32_t value) {
145 0 : return this->write(&value, 4);
146 : }
147 :
148 0 : bool SkWStream::writeScalar(SkScalar value) {
149 0 : return this->write(&value, sizeof(value));
150 : }
151 :
152 0 : bool SkWStream::writePackedUInt(size_t value) {
153 : uint8_t data[5];
154 0 : size_t len = 1;
155 0 : if (value <= SK_MAX_BYTE_FOR_U8) {
156 0 : data[0] = value;
157 0 : len = 1;
158 0 : } else if (value <= 0xFFFF) {
159 0 : uint16_t value16 = value;
160 0 : data[0] = SK_BYTE_SENTINEL_FOR_U16;
161 0 : memcpy(&data[1], &value16, 2);
162 0 : len = 3;
163 : } else {
164 0 : uint32_t value32 = value;
165 0 : data[0] = SK_BYTE_SENTINEL_FOR_U32;
166 0 : memcpy(&data[1], &value32, 4);
167 0 : len = 5;
168 : }
169 0 : return this->write(data, len);
170 : }
171 :
172 0 : bool SkWStream::writeStream(SkStream* stream, size_t length) {
173 : char scratch[1024];
174 0 : const size_t MAX = sizeof(scratch);
175 :
176 0 : while (length != 0) {
177 0 : size_t n = length;
178 0 : if (n > MAX) {
179 0 : n = MAX;
180 : }
181 0 : stream->read(scratch, n);
182 0 : if (!this->write(scratch, n)) {
183 0 : return false;
184 : }
185 0 : length -= n;
186 : }
187 0 : return true;
188 : }
189 :
190 0 : bool SkWStream::writeData(const SkData* data) {
191 0 : if (data) {
192 0 : this->write(data->data(), data->size());
193 : }
194 0 : return true;
195 : }
196 :
197 : ///////////////////////////////////////////////////////////////////////////////
198 :
199 0 : SkFILEStream::SkFILEStream(const char file[]) : fName(file)
200 : {
201 0 : fFILE = file ? sk_fopen(fName.c_str(), kRead_SkFILE_Flag) : NULL;
202 0 : }
203 :
204 0 : SkFILEStream::~SkFILEStream()
205 : {
206 0 : if (fFILE)
207 0 : sk_fclose(fFILE);
208 0 : }
209 :
210 0 : void SkFILEStream::setPath(const char path[])
211 : {
212 0 : fName.set(path);
213 0 : if (fFILE)
214 : {
215 0 : sk_fclose(fFILE);
216 0 : fFILE = NULL;
217 : }
218 0 : if (path)
219 0 : fFILE = sk_fopen(fName.c_str(), kRead_SkFILE_Flag);
220 0 : }
221 :
222 0 : const char* SkFILEStream::getFileName()
223 : {
224 0 : return fName.c_str();
225 : }
226 :
227 0 : bool SkFILEStream::rewind()
228 : {
229 0 : if (fFILE)
230 : {
231 0 : if (sk_frewind(fFILE))
232 0 : return true;
233 : // we hit an error
234 0 : sk_fclose(fFILE);
235 0 : fFILE = NULL;
236 : }
237 0 : return false;
238 : }
239 :
240 0 : size_t SkFILEStream::read(void* buffer, size_t size)
241 : {
242 0 : if (fFILE)
243 : {
244 0 : if (buffer == NULL && size == 0) // special signature, they want the total size
245 0 : return sk_fgetsize(fFILE);
246 : else
247 0 : return sk_fread(buffer, size, fFILE);
248 : }
249 0 : return 0;
250 : }
251 :
252 : ///////////////////////////////////////////////////////////////////////////////
253 :
254 0 : static SkData* newFromParams(const void* src, size_t size, bool copyData) {
255 0 : if (copyData) {
256 0 : return SkData::NewWithCopy(src, size);
257 : } else {
258 0 : return SkData::NewWithProc(src, size, NULL, NULL);
259 : }
260 : }
261 :
262 0 : SkMemoryStream::SkMemoryStream() {
263 0 : fData = SkData::NewEmpty();
264 0 : fOffset = 0;
265 0 : }
266 :
267 0 : SkMemoryStream::SkMemoryStream(size_t size) {
268 0 : fData = SkData::NewFromMalloc(sk_malloc_throw(size), size);
269 0 : fOffset = 0;
270 0 : }
271 :
272 0 : SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) {
273 0 : fData = newFromParams(src, size, copyData);
274 0 : fOffset = 0;
275 0 : }
276 :
277 0 : SkMemoryStream::~SkMemoryStream() {
278 0 : fData->unref();
279 0 : }
280 :
281 0 : void SkMemoryStream::setMemoryOwned(const void* src, size_t size) {
282 0 : fData->unref();
283 0 : fData = SkData::NewFromMalloc(src, size);
284 0 : fOffset = 0;
285 0 : }
286 :
287 0 : void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData) {
288 0 : fData->unref();
289 0 : fData = newFromParams(src, size, copyData);
290 0 : fOffset = 0;
291 0 : }
292 :
293 0 : SkData* SkMemoryStream::copyToData() const {
294 0 : fData->ref();
295 0 : return fData;
296 : }
297 :
298 0 : SkData* SkMemoryStream::setData(SkData* data) {
299 0 : SkRefCnt_SafeAssign(fData, data);
300 0 : return data;
301 : }
302 :
303 0 : void SkMemoryStream::skipToAlign4() {
304 : // cast to remove unary-minus warning
305 0 : fOffset += -(int)fOffset & 0x03;
306 0 : }
307 :
308 0 : bool SkMemoryStream::rewind() {
309 0 : fOffset = 0;
310 0 : return true;
311 : }
312 :
313 0 : size_t SkMemoryStream::read(void* buffer, size_t size) {
314 0 : size_t dataSize = fData->size();
315 :
316 0 : if (buffer == NULL && size == 0) // special signature, they want the total size
317 0 : return dataSize;
318 :
319 : // if buffer is NULL, seek ahead by size
320 :
321 0 : if (size == 0) {
322 0 : return 0;
323 : }
324 0 : if (size > dataSize - fOffset) {
325 0 : size = dataSize - fOffset;
326 : }
327 0 : if (buffer) {
328 0 : memcpy(buffer, fData->bytes() + fOffset, size);
329 : }
330 0 : fOffset += size;
331 0 : return size;
332 : }
333 :
334 0 : const void* SkMemoryStream::getMemoryBase() {
335 0 : return fData->data();
336 : }
337 :
338 0 : const void* SkMemoryStream::getAtPos() {
339 0 : return fData->bytes() + fOffset;
340 : }
341 :
342 0 : size_t SkMemoryStream::seek(size_t offset) {
343 0 : if (offset > fData->size()) {
344 0 : offset = fData->size();
345 : }
346 0 : fOffset = offset;
347 0 : return offset;
348 : }
349 :
350 : ///////////////////////////////////////////////////////////////////////////////
351 :
352 0 : SkBufferStream::SkBufferStream(SkStream* proxy, size_t bufferSize)
353 0 : : fProxy(proxy)
354 : {
355 0 : SkASSERT(proxy != NULL);
356 0 : proxy->ref();
357 0 : this->init(NULL, bufferSize);
358 0 : }
359 :
360 0 : SkBufferStream::SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize)
361 0 : : fProxy(proxy)
362 : {
363 0 : SkASSERT(proxy != NULL);
364 0 : SkASSERT(buffer == NULL || bufferSize != 0); // init(addr, 0) makes no sense, we must know how big their buffer is
365 0 : proxy->ref();
366 0 : this->init(buffer, bufferSize);
367 0 : }
368 :
369 0 : void SkBufferStream::init(void* buffer, size_t bufferSize)
370 : {
371 0 : if (bufferSize == 0)
372 0 : bufferSize = kDefaultBufferSize;
373 :
374 0 : fOrigBufferSize = bufferSize;
375 0 : fBufferSize = bufferSize;
376 0 : fBufferOffset = bufferSize; // to trigger a reload on the first read()
377 :
378 0 : if (buffer == NULL)
379 : {
380 0 : fBuffer = (char*)sk_malloc_throw(fBufferSize);
381 0 : fWeOwnTheBuffer = true;
382 : }
383 : else
384 : {
385 0 : fBuffer = (char*)buffer;
386 0 : fWeOwnTheBuffer = false;
387 : }
388 0 : }
389 :
390 0 : SkBufferStream::~SkBufferStream()
391 : {
392 0 : fProxy->unref();
393 0 : if (fWeOwnTheBuffer)
394 0 : sk_free(fBuffer);
395 0 : }
396 :
397 0 : bool SkBufferStream::rewind()
398 : {
399 0 : fBufferOffset = fBufferSize = fOrigBufferSize;
400 0 : return fProxy->rewind();
401 : }
402 :
403 0 : const char* SkBufferStream::getFileName()
404 : {
405 0 : return fProxy->getFileName();
406 : }
407 :
408 : #ifdef SK_DEBUG
409 : // #define SK_TRACE_BUFFERSTREAM
410 : #endif
411 :
412 0 : size_t SkBufferStream::read(void* buffer, size_t size) {
413 : #ifdef SK_TRACE_BUFFERSTREAM
414 : SkDebugf("Request %d", size);
415 : #endif
416 :
417 0 : if (buffer == NULL && size == 0) {
418 0 : return fProxy->read(buffer, size); // requesting total size
419 : }
420 :
421 0 : if (0 == size) {
422 0 : return 0;
423 : }
424 :
425 : // skip size bytes
426 0 : if (NULL == buffer) {
427 0 : size_t remaining = fBufferSize - fBufferOffset;
428 0 : if (remaining >= size) {
429 0 : fBufferOffset += size;
430 0 : return size;
431 : }
432 : // if we get here, we are being asked to skip beyond our current buffer
433 : // so reset our offset to force a read next time, and skip the diff
434 : // in our proxy
435 0 : fBufferOffset = fOrigBufferSize;
436 0 : return remaining + fProxy->read(NULL, size - remaining);
437 : }
438 :
439 0 : size_t s = size;
440 0 : size_t actuallyRead = 0;
441 :
442 : // flush what we can from our fBuffer
443 0 : if (fBufferOffset < fBufferSize)
444 : {
445 0 : if (s > fBufferSize - fBufferOffset)
446 0 : s = fBufferSize - fBufferOffset;
447 0 : memcpy(buffer, fBuffer + fBufferOffset, s);
448 : #ifdef SK_TRACE_BUFFERSTREAM
449 : SkDebugf(" flush %d", s);
450 : #endif
451 0 : size -= s;
452 0 : fBufferOffset += s;
453 0 : buffer = (char*)buffer + s;
454 0 : actuallyRead = s;
455 : }
456 :
457 : // check if there is more to read
458 0 : if (size)
459 : {
460 0 : SkASSERT(fBufferOffset >= fBufferSize); // need to refill our fBuffer
461 :
462 0 : if (size < fBufferSize) // lets try to read more than the request
463 : {
464 0 : s = fProxy->read(fBuffer, fBufferSize);
465 : #ifdef SK_TRACE_BUFFERSTREAM
466 : SkDebugf(" read %d into fBuffer", s);
467 : #endif
468 0 : if (size > s) // they asked for too much
469 0 : size = s;
470 0 : if (size)
471 : {
472 0 : memcpy(buffer, fBuffer, size);
473 0 : actuallyRead += size;
474 : #ifdef SK_TRACE_BUFFERSTREAM
475 : SkDebugf(" memcpy %d into dst", size);
476 : #endif
477 : }
478 :
479 0 : fBufferOffset = size;
480 0 : fBufferSize = s; // record the (possibly smaller) size for the buffer
481 : }
482 : else // just do a direct read
483 : {
484 0 : actuallyRead += fProxy->read(buffer, size);
485 : #ifdef SK_TRACE_BUFFERSTREAM
486 : SkDebugf(" direct read %d", size);
487 : #endif
488 : }
489 : }
490 : #ifdef SK_TRACE_BUFFERSTREAM
491 : SkDebugf("\n");
492 : #endif
493 0 : return actuallyRead;
494 : }
495 :
496 0 : const void* SkBufferStream::getMemoryBase()
497 : {
498 0 : return fProxy->getMemoryBase();
499 : }
500 :
501 : /////////////////////////////////////////////////////////////////////////////////////////////////////////
502 : /////////////////////////////////////////////////////////////////////////////////////////////////////////
503 :
504 0 : SkFILEWStream::SkFILEWStream(const char path[])
505 : {
506 0 : fFILE = sk_fopen(path, kWrite_SkFILE_Flag);
507 0 : }
508 :
509 0 : SkFILEWStream::~SkFILEWStream()
510 : {
511 0 : if (fFILE)
512 0 : sk_fclose(fFILE);
513 0 : }
514 :
515 0 : bool SkFILEWStream::write(const void* buffer, size_t size)
516 : {
517 0 : if (fFILE == NULL)
518 0 : return false;
519 :
520 0 : if (sk_fwrite(buffer, size, fFILE) != size)
521 : {
522 0 : SkDEBUGCODE(SkDebugf("SkFILEWStream failed writing %d bytes\n", size);)
523 0 : sk_fclose(fFILE);
524 0 : fFILE = NULL;
525 0 : return false;
526 : }
527 0 : return true;
528 : }
529 :
530 0 : void SkFILEWStream::flush()
531 : {
532 0 : if (fFILE)
533 0 : sk_fflush(fFILE);
534 0 : }
535 :
536 : ////////////////////////////////////////////////////////////////////////
537 :
538 0 : SkMemoryWStream::SkMemoryWStream(void* buffer, size_t size)
539 0 : : fBuffer((char*)buffer), fMaxLength(size), fBytesWritten(0)
540 : {
541 0 : }
542 :
543 0 : bool SkMemoryWStream::write(const void* buffer, size_t size)
544 : {
545 0 : size = SkMin32(size, fMaxLength - fBytesWritten);
546 0 : if (size > 0)
547 : {
548 0 : memcpy(fBuffer + fBytesWritten, buffer, size);
549 0 : fBytesWritten += size;
550 0 : return true;
551 : }
552 0 : return false;
553 : }
554 :
555 : ////////////////////////////////////////////////////////////////////////
556 :
557 : #define SkDynamicMemoryWStream_MinBlockSize 256
558 :
559 : struct SkDynamicMemoryWStream::Block {
560 : Block* fNext;
561 : char* fCurr;
562 : char* fStop;
563 :
564 0 : const char* start() const { return (const char*)(this + 1); }
565 0 : char* start() { return (char*)(this + 1); }
566 0 : size_t avail() const { return fStop - fCurr; }
567 0 : size_t written() const { return fCurr - this->start(); }
568 :
569 0 : void init(size_t size)
570 : {
571 0 : fNext = NULL;
572 0 : fCurr = this->start();
573 0 : fStop = this->start() + size;
574 0 : }
575 :
576 0 : const void* append(const void* data, size_t size)
577 : {
578 0 : SkASSERT((size_t)(fStop - fCurr) >= size);
579 0 : memcpy(fCurr, data, size);
580 0 : fCurr += size;
581 0 : return (const void*)((const char*)data + size);
582 : }
583 : };
584 :
585 0 : SkDynamicMemoryWStream::SkDynamicMemoryWStream()
586 0 : : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopy(NULL)
587 : {
588 0 : }
589 :
590 0 : SkDynamicMemoryWStream::~SkDynamicMemoryWStream()
591 : {
592 0 : reset();
593 0 : }
594 :
595 0 : void SkDynamicMemoryWStream::reset()
596 : {
597 0 : this->invalidateCopy();
598 :
599 0 : Block* block = fHead;
600 :
601 0 : while (block != NULL) {
602 0 : Block* next = block->fNext;
603 0 : sk_free(block);
604 0 : block = next;
605 : }
606 0 : fHead = fTail = NULL;
607 0 : fBytesWritten = 0;
608 0 : }
609 :
610 0 : bool SkDynamicMemoryWStream::write(const void* buffer, size_t count)
611 : {
612 0 : if (count > 0) {
613 0 : this->invalidateCopy();
614 :
615 0 : fBytesWritten += count;
616 :
617 : size_t size;
618 :
619 0 : if (fTail != NULL && fTail->avail() > 0) {
620 0 : size = SkMin32(fTail->avail(), count);
621 0 : buffer = fTail->append(buffer, size);
622 0 : SkASSERT(count >= size);
623 0 : count -= size;
624 0 : if (count == 0)
625 0 : return true;
626 : }
627 :
628 0 : size = SkMax32(count, SkDynamicMemoryWStream_MinBlockSize);
629 0 : Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size);
630 0 : block->init(size);
631 0 : block->append(buffer, count);
632 :
633 0 : if (fTail != NULL)
634 0 : fTail->fNext = block;
635 : else
636 0 : fHead = fTail = block;
637 0 : fTail = block;
638 : }
639 0 : return true;
640 : }
641 :
642 0 : bool SkDynamicMemoryWStream::write(const void* buffer, size_t offset, size_t count)
643 : {
644 0 : if (offset + count > fBytesWritten) {
645 0 : return false; // test does not partially modify
646 : }
647 :
648 0 : this->invalidateCopy();
649 :
650 0 : Block* block = fHead;
651 0 : while (block != NULL) {
652 0 : size_t size = block->written();
653 0 : if (offset < size) {
654 0 : size_t part = offset + count > size ? size - offset : count;
655 0 : memcpy(block->start() + offset, buffer, part);
656 0 : if (count <= part)
657 0 : return true;
658 0 : count -= part;
659 0 : buffer = (const void*) ((char* ) buffer + part);
660 : }
661 0 : offset = offset > size ? offset - size : 0;
662 0 : block = block->fNext;
663 : }
664 0 : return false;
665 : }
666 :
667 0 : bool SkDynamicMemoryWStream::read(void* buffer, size_t offset, size_t count)
668 : {
669 0 : if (offset + count > fBytesWritten)
670 0 : return false; // test does not partially modify
671 0 : Block* block = fHead;
672 0 : while (block != NULL) {
673 0 : size_t size = block->written();
674 0 : if (offset < size) {
675 0 : size_t part = offset + count > size ? size - offset : count;
676 0 : memcpy(buffer, block->start() + offset, part);
677 0 : if (count <= part)
678 0 : return true;
679 0 : count -= part;
680 0 : buffer = (void*) ((char* ) buffer + part);
681 : }
682 0 : offset = offset > size ? offset - size : 0;
683 0 : block = block->fNext;
684 : }
685 0 : return false;
686 : }
687 :
688 0 : void SkDynamicMemoryWStream::copyTo(void* dst) const
689 : {
690 0 : if (fCopy) {
691 0 : memcpy(dst, fCopy->data(), fBytesWritten);
692 : } else {
693 0 : Block* block = fHead;
694 :
695 0 : while (block != NULL) {
696 0 : size_t size = block->written();
697 0 : memcpy(dst, block->start(), size);
698 0 : dst = (void*)((char*)dst + size);
699 0 : block = block->fNext;
700 : }
701 : }
702 0 : }
703 :
704 0 : void SkDynamicMemoryWStream::padToAlign4()
705 : {
706 : // cast to remove unary-minus warning
707 0 : int padBytes = -(int)fBytesWritten & 0x03;
708 0 : if (padBytes == 0)
709 0 : return;
710 0 : int zero = 0;
711 0 : write(&zero, padBytes);
712 : }
713 :
714 0 : SkData* SkDynamicMemoryWStream::copyToData() const {
715 0 : if (NULL == fCopy) {
716 0 : void* buffer = sk_malloc_throw(fBytesWritten);
717 0 : this->copyTo(buffer);
718 0 : fCopy = SkData::NewFromMalloc(buffer, fBytesWritten);
719 : }
720 0 : fCopy->ref();
721 0 : return fCopy;
722 : }
723 :
724 0 : void SkDynamicMemoryWStream::invalidateCopy() {
725 0 : if (fCopy) {
726 0 : fCopy->unref();
727 0 : fCopy = NULL;
728 : }
729 0 : }
730 :
731 : ///////////////////////////////////////////////////////////////////////////////
732 :
733 0 : void SkDebugWStream::newline()
734 : {
735 : #ifdef SK_DEBUG
736 0 : SkDebugf("\n");
737 : #endif
738 0 : }
739 :
740 0 : bool SkDebugWStream::write(const void* buffer, size_t size)
741 : {
742 : #ifdef SK_DEBUG
743 0 : char* s = new char[size+1];
744 0 : memcpy(s, buffer, size);
745 0 : s[size] = 0;
746 0 : SkDebugf("%s", s);
747 0 : delete[] s;
748 : #endif
749 0 : return true;
750 : }
|