/*****************************************************************************

 @(#) $Id: Codec.H,v 1.3 2000/10/13 15:45:51 brian Exp $

 -----------------------------------------------------------------------------

 Copyright (C) 1997-2000  Brian Bidulock <bidulock@dallas.net>

 All Rights Reserved.

 This library is free software; you can redistribute it and/or modify it under
 the terms of the GNU Lesser General Public License as published by the Free
 Software Foundation; either version 2.1 of the License, or (at your option)
 any later version.
 
 This library is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the GNU Lesser Public License for more
 details.
 
 You should have received a copy of the GNU Lesser General Public License
 along with this library; if not, write to the Free Software Foundation, Inc.,
 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

 Last Modified $Date: 2000/10/13 15:45:51 $ by $Author: brian $

 -----------------------------------------------------------------------------

 $Log: Codec.H,v $
 Revision 1.3  2000/10/13 15:45:51  brian
 First public release.

 *****************************************************************************/

#ifndef __SS7_CODEC_H__
#define __SS7_CODEC_H__

#include <values.h>

class Error {
    public:
        char* desc;
        char* label;
        virtual void errout();
        Error(char*,char*);
    };

class Invalid : public Error { public: Invalid(char*); }; 
class Bounds  : public Error { public: Bounds (char*); };
class Repeats : public Error { public: Repeats(char*); };
class SpecErr : public Error { public: SpecErr(char*); };
class NullPtr : public Error { public: NullPtr(char*); };

class NewFlag {
    private:
        static int crumb;
        int value;
    public:
        NewFlag();
        NewFlag(bool);
        NewFlag(int);
        operator bool();
        operator int();
        static void clearFlags();
    };

class FramePointer {
    public:
        char*   pointer;    // pointer to start of frame
        int     length;     // bit length of frame
        int     offset;     // bit offset into frame
        int     end;        // bit offset of end of frame
        int     size;       // bit size of something in frame

        char*   point();        // point to offset
        void    set(char*,int); // set the pointer
        
        FramePointer(char*,int);
        FramePointer();
        operator char*();
        operator void*();
        operator int();
    };

class Codec;

class Level {
    public:
        Codec*  codec;                  // codec for this level
        
        virtual void decode(FramePointer&);  // decode method for this level
        virtual void encode(FramePointer&);  // encode method for this level
        virtual void report();               // report method for this level
    };

class Field;

class Codec {
    public:
        static int      bldseq;     // build sequence number
        enum { ccitt, ansi };
        static int      variant;
        static NewFlag  pass2;      // is this pass 2?
        static NewFlag  pass2req;   // is second pass required?
        char*           label;
        char*           title;
        char*           mnem;
        char*           text;
        int             size;
        int             spare;
        int             dfltval;
        int             value;
        int             bldord;     // build order number
        FramePointer    frame;
        NewFlag         exists;     // does this object exist?
        NewFlag         built;      // was this object built?
        NewFlag         bound;      // was this object bound?
        NewFlag         invalid;    // is this object valid?
        bool            master;     // master copy
        
        virtual void decode(FramePointer&);  // decode method for this level
        virtual void encode(FramePointer&);  // encode method for this level
        virtual void report();               // report method for this level
        virtual void bits(int);              // report bits
        virtual void morebits();             // report more bits
        
        virtual void build();               // build one of these

        virtual bool set(int);              // set value by value
        virtual bool set(char*);            // set value by mnemonic
        virtual bool set(char*,int);        // set value by pointer
        
        virtual bool get(int&);             // get value by value
        virtual bool get(char*&);           // get value by mnemonic
        virtual bool get(char*&,int&);      // get value by pointer
        
        virtual bool test(int);             // test value by value
        virtual bool test(char*,int);       // test value by pointer
        virtual bool test(char*);           // test value by mnemonic

        static bool decode(Codec*,char*,int);   // decode the frame
        static bool encode(Codec*,char*,int&);  // encode the frame
        static void report(Codec*);             // report the frame
        static void rebuild();                  // rebuild the frame
        
        Codec(char*,char*,int,int);
        Codec(const Codec&);
        virtual Codec* copy();
        virtual Codec* newcopy(char*,char*);
        virtual ~Codec();
    };

class Content;

class List : public Codec {
    public:
        int     contents;
        int     branches;
        Codec** content;
        
        void decode(FramePointer&);  // decode method for this level
        void encode(FramePointer&);  // encode method for this level
        void report();               // report method for this level
        
        List(char*,char*,int,int,int,Codec**);
        List(const List&);
        List* newcopy(char*,char*);
        ~List();
    };

class Header : public List {
    public:
        Header(char*,char*,int,int,int,Codec**);
    };


class Content : public List {
    public:
        Content(char*,char*,int,int,int,Codec**);
    };

class Parameter : public List {
    public:
        Parameter(char*,char*,int,int,int,Codec**);
        Parameter(const Parameter&);
    };

class ParameterG : public Parameter {
    public:
        ParameterG(char*,char*,...);
        ParameterG(const ParameterG&);
        ~ParameterG();
    };

class ParameterR : public Parameter {
    public:
        ParameterR* next;
        void decode(FramePointer&);  // decode method for this level
        void encode(FramePointer&);  // encode method for this level
        void report();               // report method for this level
        
        ParameterR(char*,char*,int,int,int,Codec**);
        ParameterR(ParameterR&);
        ParameterR* copy();
        ParameterR* newcopy(char*,char*);
        ~ParameterR();
    };

class ParameterP : public Parameter {
    public:
        void decode(FramePointer&);  // decode method for this level
        void encode(FramePointer&);  // encode method for this level
        
        ParameterP(char*,char*,int,int,int,Codec**);
    };

class ParameterPL : public Parameter {
    public:
        void decode(FramePointer&);  // decode method for this level
        void encode(FramePointer&);  // encode method for this level
        
        ParameterPL(char*,char*,int,int,int,Codec**);
    };

class ParameterPNL : public Parameter {
    public:
        ParameterPNL* next;
        void decode(FramePointer&);  // decode method for this level
        void encode(FramePointer&);  // encode method for this level
        void report();               // report method for this level
        
        ParameterPNL(char*,char*,int,int,int,Codec**);
        ParameterPNL(ParameterPNL&);
        ParameterPNL* newcopy(char*,char*);
        ~ParameterPNL();
    };

class ParameterNL : public Parameter {
    public:
        ParameterNL* next;
        void decode(FramePointer&);  // decode method for this level
        void encode(FramePointer&);  // encode method for this level
        void report();               // report method for this level
        
        ParameterNL(char*,char*,int,int,int,Codec**);
        ParameterNL(ParameterNL&);
        ParameterNL* newcopy(char*,char*);
        ~ParameterNL();
    };

class OctetString : public Codec {
    public:
        void decode(FramePointer&);  // decode method for this level
        void encode(FramePointer&);  // encode method for this level
        void report();               // report method for this level
        
        OctetString(char*,char*,int);
    };

class DigitString : public OctetString {
    public:
        void report();               // report method for this level
        
        DigitString(char*,char*,int);
    };

class AsciiString : public OctetString {
    public:
        void report();               // report method for this level
        
        AsciiString(char*,char*,int);
    };

class Field : public Codec {
    public:
        void decode(FramePointer&);  // decode method for this level
        void encode(FramePointer&);  // encode method for this level
        void report();               // report method for this level
        
        Field(char*,char*,int,int);
    };

class Set : public Field {
    protected:
        int     vals;
        struct SetStr { int indx; char* mnem; char* text; } *val;
    public:
        void decode(FramePointer&);  // decode method for this level
        void encode(FramePointer&);  // encode method for this level
        void report();               // report method for this level
        
        bool set(int);              // set value by value
        bool set(char*);            // set value by mnemonic
        bool set(char*,int);        // set value by pointer
        
        bool get(int&);             // get value by value
        bool get(char*&);           // get value by mnemonic
        bool get(char*&,int&);      // get value by pointer
        
        bool test(int);             // test value by value
        bool test(char*);           // test value by mnemonic
        bool test(char*,int);       // test value by pointer
        
        
        Set(char*,char*,int,int,...);
        ~Set();
    };

class Bra : public Codec {
    friend ParameterPNL;
    friend ParameterNL;
    protected:
        int     vals;
        struct  BraStr { int indx; Codec* path; } *val;
    public:
        Codec* branch;
        void decode(FramePointer&);  // decode method for this level
        void encode(FramePointer&);  // encode method for this level
        void report();               // report method for this level
        
        bool set(char*);            // set value by mnemonic
        bool get(char*&);           // get value by mnemonic
        bool test(char*);           // test value by pointer
        
        Bra(char*,char*,Codec*,...);
        Bra(const Bra&);
        ~Bra();
    };

#endif __SS7_CODEC_H__


