00001 /* 00002 * Copyright (C) 2008 The Android Open Source Project 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef SkReader32_DEFINED 00018 #define SkReader32_DEFINED 00019 00020 #include "SkTypes.h" 00021 00022 #include "SkScalar.h" 00023 #include "SkPoint.h" 00024 #include "SkRect.h" 00025 00026 class SkReader32 : SkNoncopyable { 00027 public: 00028 SkReader32() : fCurr(NULL), fStop(NULL), fBase(NULL) {} 00029 SkReader32(const void* data, size_t size) { 00030 this->setMemory(data, size); 00031 } 00032 00033 void setMemory(const void* data, size_t size) { 00034 SkASSERT(ptr_align_4(data)); 00035 SkASSERT(SkAlign4(size) == size); 00036 00037 fBase = fCurr = (const char*)data; 00038 fStop = (const char*)data + size; 00039 } 00040 00041 uint32_t size() const { return fStop - fBase; } 00042 uint32_t offset() const { return fCurr - fBase; } 00043 bool eof() const { return fCurr >= fStop; } 00044 const void* base() const { return fBase; } 00045 const void* peek() const { return fCurr; } 00046 void rewind() { fCurr = fBase; } 00047 00048 void setOffset(size_t offset) { 00049 SkASSERT(SkAlign4(offset) == offset); 00050 SkASSERT(offset <= this->size()); 00051 fCurr = fBase + offset; 00052 } 00053 00054 bool readBool() { return this->readInt() != 0; } 00055 00056 int32_t readInt() { 00057 SkASSERT(ptr_align_4(fCurr)); 00058 int32_t value = *(const int32_t*)fCurr; 00059 fCurr += sizeof(value); 00060 SkASSERT(fCurr <= fStop); 00061 return value; 00062 } 00063 00064 SkScalar readScalar() { 00065 SkASSERT(ptr_align_4(fCurr)); 00066 SkScalar value = *(const SkScalar*)fCurr; 00067 fCurr += sizeof(value); 00068 SkASSERT(fCurr <= fStop); 00069 return value; 00070 } 00071 00072 const SkPoint* skipPoint() { 00073 return (const SkPoint*)this->skip(sizeof(SkPoint)); 00074 } 00075 00076 const SkRect* skipRect() { 00077 return (const SkRect*)this->skip(sizeof(SkRect)); 00078 } 00079 00080 const void* skip(size_t size) { 00081 SkASSERT(ptr_align_4(fCurr)); 00082 const void* addr = fCurr; 00083 fCurr += SkAlign4(size); 00084 SkASSERT(fCurr <= fStop); 00085 return addr; 00086 } 00087 00088 void read(void* dst, size_t size) { 00089 SkASSERT(dst != NULL); 00090 SkASSERT(ptr_align_4(fCurr)); 00091 memcpy(dst, fCurr, size); 00092 fCurr += SkAlign4(size); 00093 SkASSERT(fCurr <= fStop); 00094 } 00095 00096 uint8_t readU8() { return (uint8_t)this->readInt(); } 00097 uint16_t readU16() { return (uint16_t)this->readInt(); } 00098 int32_t readS32() { return this->readInt(); } 00099 uint32_t readU32() { return this->readInt(); } 00100 00101 private: 00102 // these are always 4-byte aligned 00103 const char* fCurr; // current position within buffer 00104 const char* fStop; // end of buffer 00105 const char* fBase; // beginning of buffer 00106 00107 #ifdef SK_DEBUG 00108 static bool ptr_align_4(const void* ptr) 00109 { 00110 return (((const char*)ptr - (const char*)NULL) & 3) == 0; 00111 } 00112 #endif 00113 }; 00114 00115 #endif