/**************************************************************************
 *
 * UCArray.h -- vector based string class
 * Copyright (C) 1999  Rodger McNab
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 **************************************************************************/

#ifndef UCARRAY_H
#define UCARRAY_H

#include "mglong.h"

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
#pragma warning(disable:4786)
#endif

// need this to avoid bizarre compiler problems under VC++ 6.0
#if !defined (GSDL_NAMESPACE_BROKEN) && !defined (GSDL_USE_IOS_H)
# include <iostream>
using namespace std;
#endif

#if defined(GSDL_USE_OBJECTSPACE)
#  include <ospace\std\vector>
#  include <ospace\std\set>
#elif defined(GSDL_USE_STL_H)
#  include <vector.h>
#  include <set.h>
#else
#  include <vector>
#  include <set>
#endif

#if defined(GSDL_USE_OBJECTSPACE)
#  include <ospace\std\iostream>
#elif defined(GSDL_USE_IOS_H)
#  include <iostream.h>
#else
#  include <iostream>
#endif

#include <stdio.h>
#include <cstring>


typedef vector<unsigned char> UCArray;

// functions to manipulate UCArrays
void SetCStr (UCArray &text, const char *cStr);
// same as SetCStr but first tries to allocate nSizeHint space (only if needed)
void SetCStr (UCArray &text, const char *cStr, size_t nSizeHint);
char * GetCStr(const UCArray& text);
inline void UCArrayClear (UCArray &a) {
  a.erase (a.begin(), a.end());
}
bool UCArrayCStrEquals(const UCArray &text, const unsigned char *cStr);
inline bool UCArrayCStrEquals(const UCArray &text, const char *cStr) { return UCArrayCStrEquals(text, (const unsigned char *)cStr); }

// stream operator to print UCArray
ostream &operator<<(ostream &s, const UCArray &a);

// used for reading and writing unsigned characters
inline bool ReadUC (FILE *f, unsigned char &c) {
  return (fread (&c, sizeof (unsigned char), 1, f) == 1);
}
inline bool WriteUC (FILE *f, unsigned char c) {
  return (fwrite (&c, sizeof (unsigned char), 1, f) == 1);
}

// used for reading and writing variable length unsigned longs
bool ReadVarLenUL (FILE *f, mg_u_long &n);
bool WriteVarLenUL (FILE *f, mg_u_long n);

// used for reading and writing unsigned longs 
bool ReadUL (FILE *f, mg_u_long &n);
bool WriteUL (FILE *f, mg_u_long n);

// used for reading and writing floats
bool ReadF (FILE *f, float &n);
bool WriteF (FILE *f, float n);

// used for reading and writing doubles
bool ReadD (FILE *f, double &n);
bool WriteD (FILE *f, double n);

// used for reading and writing arrays to files
bool ReadUCArray (FILE *f, UCArray &a);
bool WriteUCArray (FILE *f, const UCArray &a);


// compares the two strings in dictionary order
int DictCompare (const UCArray &a1, const UCArray &a2);

// does the first string start with the second?
bool StartsWith(const UCArray &a1, const UCArray &a2);
// does the first string start with the second, ignoring case?
bool StartsWithCasefold(const UCArray &a1, const UCArray &a2);

struct LTUCArray {
  bool operator()(const UCArray &a1, const UCArray &a2) const
    { return (a1 < a2); }
};

struct DictLTUCArray {
  bool operator() (const UCArray &a1, const UCArray &a2) const
    { return (DictCompare (a1, a2) < 0); }
};


typedef set<UCArray, LTUCArray> UCArraySet;
typedef vector<UCArray> UCArrayVector;

mg_u_long PrefixLen (const UCArray &a1, const UCArray &a2);

// prev == NULL if no previous string
bool WritePreSufStr (FILE *f, const UCArray *prev, const UCArray &a);
bool ReadPreSufStr (FILE *f, UCArray &a); // a also used for prev


#endif
