// encode.h - Term encoding and decoding. // // ##Copyright## // // Copyright 2000-2016 Peter Robinson (pjr@itee.uq.edu.au) // // Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.00 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // ##Copyright## // // $Id: encode.h,v 1.11 2005/03/27 22:07:39 qp Exp $ #ifndef ENCODE_H #define ENCODE_H #include "atom_table.h" #include "objects.h" #include "defs.h" // #include "io_qp.h" #include class Heap; class NameTable; class Thread; // // Map the (meta and object) variables and atoms into unique entries. // class EncodeMap { private: // // The array index cannot be larger than 1 byte because the encoder // sends 1 byte. // Therefore we consider a vector of tables with the max length of the // vector being 256. static const int TABLE_MAX = 256; #ifdef WIN32 vector > vector_of_tables; #else vector vector_of_tables; #endif int top_table_entry; int top_vector_entry; public: static const int32 NOT_FOUND = -1; static const word8 ENCODE_REFERENCE = 0; static const word8 ENCODE_VARIABLE = 1; static const word8 ENCODE_OB_REFERENCE = 2; static const word8 ENCODE_OB_VARIABLE = 3; static const word8 ENCODE_LIST = 4; static const word8 ENCODE_STRUCTURE = 5; static const word8 ENCODE_QUANTIFIER = 6; static const word8 ENCODE_ATOM_REF = 7; static const word8 ENCODE_ATOM = 8; static const word8 ENCODE_INTEGER = 9; static const word8 ENCODE_SUBSTITUTION = 10; static const word8 ENCODE_SUBSTITUTION_END = 11; static const word8 ENCODE_NAME = 12; static const word8 ENCODE_REF_OFFSET = 13; static const word8 ENCODE_DOUBLE = 14; static const word8 ENCODE_STRING = 15; // // Add. // void add(Object* c) { if (top_table_entry < TABLE_MAX) { vector_of_tables[top_vector_entry-1][top_table_entry++] = c; } else { if (top_vector_entry == TABLE_MAX) { cerr << "Not enough space to encode term" << endl; exit(1); } vector_of_tables.push_back(new Object* [TABLE_MAX]); top_table_entry = 0; vector_of_tables[top_vector_entry++][top_table_entry++] = c; } } // // Look-up. // Object* lookUp(word8 i, word8 j) { return(vector_of_tables[i][j]); } int32 lookUp(Object* c) { int i; int j; for (i = 0; i < top_table_entry; i++) { if (vector_of_tables[top_vector_entry-1][i] == c) { return(TABLE_MAX*(top_vector_entry-1) + i); } } for (j = 0; j < top_vector_entry-1; j++) { for (i = 0; i < TABLE_MAX; i++) { if (vector_of_tables[j][i] == c) { return(TABLE_MAX*j + i); } } } return(NOT_FOUND); } Object* getObjectVariableNames(Heap&); EncodeMap(void) { #ifdef WIN32 //Or windows will die vector_of_tables.reserve(1); #endif vector_of_tables.push_back(new Object*[TABLE_MAX]); top_table_entry = 0; top_vector_entry = 1; } ~EncodeMap(void) { for (int i = 0; i < top_vector_entry; i++) { delete [] vector_of_tables[i]; } top_table_entry = 0; } }; // // Auxiliary class bundles up some useful things. // class EncodeBase { protected: bool success; EncodeMap *map; public: EncodeBase(void) : map(new EncodeMap()) { } ~EncodeBase(void) { delete map; } bool Success(void) const { return success; } }; class EncodeWrite : public EncodeBase { private: // // Write a character. // bool writeEncodeChar(QPStream&, const word8); // // Encode write a number // bool writeEncodeNumber(QPStream&, const qint64); // // Encode write a double // bool writeEncodeDouble(QPStream&, const double); // // Encode the atom and write the result to the stream. // bool encodeWriteAtom(QPStream&, Atom*, AtomTable& atoms); // // Encode the string and write the result to the stream. // bool encodeWriteString(QPStream&, char*); // // Encode the variable name and sent it over. // bool encodeWriteVarName(Heap&, QPStream&, Object*, AtomTable&); // // Encode the substitution and write the result to the stream. // bool encodeWriteSub(Thread&, Heap&, QPStream&, Object*, AtomTable&, const bool, NameTable&); bool encodeWriteTerm(Thread&, Heap&, QPStream&, Object*, AtomTable&, const bool, NameTable&); public: EncodeWrite(Thread& th, Heap& heap, QPStream& stream, Object* term, AtomTable& atoms, const bool remember, NameTable& names) { success = encodeWriteTerm(th, heap, stream, term, atoms, remember, names); } }; class EncodeRead : public EncodeBase { private: char *stringbuff; // // Read a character. // bool encodeReadChar(QPStream&, word8&); // // Read from a stream and decode back to a string. // bool encodeReadString(QPStream&, Object*&, Heap&); // // Read from a stream and decode back to an atom. // bool encodeReadAtom(QPStream&, Atom*&, AtomTable&); // // Read a number. // bool encodeReadNumber(QPStream&, qint64&); // // Read a double. // bool encodeReadDouble(QPStream&, double&); // // Read from a stream and decode back to the substitution. // bool encodeReadSub(Thread&, Heap&, QPStream&, Object*&, AtomTable&, const bool, NameTable&); bool encodeReadTerm(Thread&, Heap&, QPStream&, Object*&, AtomTable&, const bool, NameTable&); public: // // Read from a stream and decode back to the term. // EncodeRead(Thread& th, Heap& heap, QPStream& stream, Object*& term, AtomTable& atoms, const bool remember, NameTable& names, Object*& name_list) : stringbuff(new char[ATOM_LENGTH]) { success = encodeReadTerm(th, heap, stream, term, atoms, remember, names); if (success) { name_list = map->getObjectVariableNames(heap); } } ~EncodeRead(void) { delete [] stringbuff; } }; #endif // ENCODE_H