/* * PROGRAM: Client/Server Common Code * MODULE: ClumpletReader.h * DESCRIPTION: Secure handling of clumplet buffers * * The contents of this file are subject to the Initial * Developer's Public License Version 1.0 (the "License"); * you may not use this file except in compliance with the * License. You may obtain a copy of the License at * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. * * Software distributed under the License is distributed AS IS, * WITHOUT WARRANTY OF ANY KIND, either express or implied. * See the License for the specific language governing rights * and limitations under the License. * * The Original Code was created by Nickolay Samofatov * for the Firebird Open Source RDBMS project. * * Copyright (c) 2004 Nickolay Samofatov * and all contributors signed below. * * All Rights Reserved. * Contributor(s): ______________________________________. * * */ #ifndef CLUMPLETREADER_H #define CLUMPLETREADER_H #include "../common/classes/alloc.h" #include "../common/classes/array.h" #include "../common/classes/fb_string.h" #define DEBUG_CLUMPLETS #if defined(DEV_BUILD) && !defined(DEBUG_CLUMPLETS) #define DEBUG_CLUMPLETS #endif namespace Firebird { // This class provides read access for clumplet structure // Note: it doesn't make a copy of buffer it reads class ClumpletReader : protected AutoStorage { public: enum Kind {Tagged, UnTagged, SpbAttach, SpbStart, Tpb/*, SpbInfo*/}; // Constructor prepares an object from plain PB ClumpletReader(Kind k, const UCHAR* buffer, size_t buffLen); virtual ~ClumpletReader() { } // Navigation in clumplet buffer bool isEof() const { return cur_offset >= getBufferLength(); } void moveNext(); void rewind(); bool find(UCHAR tag); // Methods which work with currently selected clumplet UCHAR getClumpTag() const; size_t getClumpLength() const; SLONG getInt() const; bool getBoolean() const; SINT64 getBigInt() const; string& getString(string& str) const; PathName& getPath(PathName& str) const; const UCHAR* getBytes() const; // Return the tag for buffer (usually structure version) UCHAR getBufferTag() const; size_t getBufferLength() const { size_t rc = getBufferEnd() - getBuffer(); if (rc == 1 && kind != UnTagged && kind != SpbStart) { rc = 0; } return rc; } size_t getCurOffset() const { return cur_offset; } void setCurOffset(size_t newOffset) { cur_offset = newOffset; } #ifdef DEBUG_CLUMPLETS // Sometimes it's really useful to have it in case of errors void dump() const; #endif protected: enum ClumpletType {TraditionalDpb, SingleTpb, StringSpb, IntSpb, ByteSpb}; ClumpletType getClumpletType(UCHAR tag) const; size_t getClumpletSize(bool wTag, bool wLength, bool wData) const; void adjustSpbState(); size_t cur_offset; const Kind kind; UCHAR spbState; // Reflects state of spb parser/writer // Methods are virtual so writer can override 'em virtual const UCHAR* getBuffer() const { return static_buffer; } virtual const UCHAR* getBufferEnd() const { return static_buffer_end; } // These functions are called when error condition is detected by this class. // They may throw exceptions. If they don't reader tries to do something // sensible, certainly not overwrite memory or read past the end of buffer // This appears to be a programming error in buffer access pattern virtual void usage_mistake(const char* what) const; // This is called when passed buffer appears invalid virtual void invalid_structure(const char* what) const; private: // Assignment and copy constructor not implemented. ClumpletReader(const ClumpletReader& from); ClumpletReader& operator=(const ClumpletReader& from); const UCHAR* static_buffer; const UCHAR* static_buffer_end; }; } // namespace Firebird #endif // CLUMPLETREADER_H