add readPtr and writePtr to SkReader32 and SkWriter32

add template helper SkSWriter32, which allocates initial storage buffer
Review URL: https://codereview.appspot.com/6299075

git-svn-id: http://skia.googlecode.com/svn/trunk@4237 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2012-06-12 20:47:53 +00:00
Родитель 64a0ec3655
Коммит 51c62a6cfa
3 изменённых файлов: 74 добавлений и 5 удалений

Просмотреть файл

@ -58,7 +58,19 @@ public:
SkASSERT(fCurr <= fStop);
return value;
}
void* readPtr() {
void* ptr;
// we presume this "if" is resolved at compile-time
if (4 == sizeof(void*)) {
ptr = *(void**)fCurr;
} else {
memcpy(&ptr, fCurr, sizeof(void*));
}
fCurr += sizeof(void*);
return ptr;
}
SkScalar readScalar() {
SkASSERT(ptr_align_4(fCurr));
SkScalar value = *(const SkScalar*)fCurr;

Просмотреть файл

@ -77,6 +77,17 @@ public:
*(int32_t*)this->reserve(sizeof(value)) = value;
}
void writePtr(void* ptr) {
// Since we "know" that we're always 4-byte aligned, we can tell the
// compiler that here, by assigning to an int32 ptr.
int32_t* addr = (int32_t*)this->reserve(sizeof(void*));
if (4 == sizeof(void*)) {
*(void**)addr = ptr;
} else {
memcpy(addr, &ptr, sizeof(void*));
}
}
void writeScalar(SkScalar value) {
*(SkScalar*)this->reserve(sizeof(value)) = value;
}
@ -176,4 +187,22 @@ private:
Block* newBlock(size_t bytes);
};
/**
* Helper class to allocated SIZE bytes as part of the writer, and to provide
* that storage to the constructor as its initial storage buffer.
*
* This wrapper ensures proper alignment rules are met for the storage.
*/
template <size_t SIZE> class SkSWriter32 : public SkWriter32 {
public:
SkSWriter32(size_t minSize) : SkWriter32(minSize, fData.fStorage, SIZE) {}
private:
union {
void* fPtrAlignment;
double fDoubleAlignment;
char fStorage[SIZE];
} fData;
};
#endif

Просмотреть файл

@ -12,6 +12,34 @@
#include "SkWriter32.h"
#include "Test.h"
static void test_ptr(skiatest::Reporter* reporter) {
SkSWriter32<32> writer(32);
void* p0 = reporter;
void* p1 = &writer;
// try writing ptrs where at least one of them may be at a non-multiple of
// 8 boundary, to confirm this works on 64bit machines.
writer.writePtr(p0);
writer.write8(0x33);
writer.writePtr(p1);
writer.write8(0x66);
size_t size = writer.size();
REPORTER_ASSERT(reporter, 2 * sizeof(void*) + 2 * sizeof(int32_t));
char buffer[32];
SkASSERT(sizeof(buffer) >= size);
writer.flatten(buffer);
SkReader32 reader(buffer, size);
REPORTER_ASSERT(reporter, reader.readPtr() == p0);
REPORTER_ASSERT(reporter, reader.readInt() == 0x33);
REPORTER_ASSERT(reporter, reader.readPtr() == p1);
REPORTER_ASSERT(reporter, reader.readInt() == 0x66);
}
static void test1(skiatest::Reporter* reporter, SkWriter32* writer) {
const uint32_t data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (size_t i = 0; i < SK_ARRAY_COUNT(data); ++i) {
@ -79,8 +107,7 @@ static void Tests(skiatest::Reporter* reporter) {
// small storage
{
intptr_t storage[8];
SkWriter32 writer(100, storage, sizeof(storage));
SkSWriter32<8 * sizeof(intptr_t)> writer(100);
test1(reporter, &writer);
writer.reset(); // should just rewind our storage
test2(reporter, &writer);
@ -88,12 +115,13 @@ static void Tests(skiatest::Reporter* reporter) {
// large storage
{
intptr_t storage[1024];
SkWriter32 writer(100, storage, sizeof(storage));
SkSWriter32<1024 * sizeof(intptr_t)> writer(100);
test1(reporter, &writer);
writer.reset(); // should just rewind our storage
test2(reporter, &writer);
}
test_ptr(reporter);
}
#include "TestClassDef.h"