#ifndef ALREADY_INCLUDED_STRING_HH
#define ALREADY_INCLUDED_STRING_HH
#include <string.h> /* for strcmp */
#include "../noallegro/my-allegro.hh"
//class string;
//class string_buffer;
class String_Internal
{
public:
static const int MIN_LENGTH = 50; // was 50
int ref_count;
int length;
int maxlength;
char array[1]; // GUARANTEED: array[length] == '\0'
// note the extra 1 here means that the
// following invariant must hold: length <= maxlength
// so appending can occur if length < maxlength
public:
/* Similar to a constructor, but lower level. Called
* after a malloc call like so:
*
* ptr = (String_Internal*)malloc(sizeof(String_Internal) + newlen);
* ptr->init(newlen);
*/
void init(int maxlength)
{
this->ref_count = 1;
this->length = 0;
this->maxlength = maxlength;
this->array[0] = 0;
}
};
/* This class is a reference-counted pointer to
* the true String_Internal object.
*/
class string
{
protected:
String_Internal* ptr;
void worker_current_down() { if (--ptr->ref_count == 0) { delete ptr; ptr = null; } }
void worker_new_up(const string& s) { s.ptr->ref_count++; }
void worker_mutator_clone();
/* The advantage of this function over the standard
* C library strncpy is that this one returns the
* number of characters copied.
*/
friend int my_strncpy(char* to, const char* from, int mem_size);
public:
/* STANDARD FOUR BASIC OPERATIONS: */
string();
string(const string& s);
string& operator = (const string& s);
~string();
/* END STANDARD FOUR BASIC OPERATIONS! */
/*
* Needed so you can write:
* string s = 'c';
*/
string(char ch);
/*
* Needed so you can write:
* string s = 123;
*/
string(int i);
/*
* Needed so you can write:
* string s = 123.456;
*/
string(double d);
/*
* Needed so you can write:
* string s = "hello";
*/
string(const char* s);
/*
* Needed so you can write:
* string s;
* s = "hello";
*/
string& operator = (const char* s);
/*
* Needed so you can write:
* string s;
* s += "hello";
*/
string& operator += (const string& s);
string& operator += (const char* s);
/*
* patterned after Java's equals method.
*/
bool equals(const string& other) const
{
return !(strcmp(this->ptr->array, other.ptr->array));
}
bool equals(const char* other) const
{
return !(strcmp(this->ptr->array, other));
}
/*
* Needed so you can access legacy const char* functions
*
*/
const char* const_char_star() const {
return ptr->array;
}
//operator const char*() const;
/*
* For accessing legacy (non-const) char* functions:
*
* Example:
*
* void foo(string s, int bar)
* {
* const int MAX_LENGTH = 200
* char array[MAX_LENGTH];
* sprintf(s.char_star(MAX_LENGTH,array),"bar=%d\n", bar);
* cout << s;
* }
*/
char* char_star(int mem_size, char * s) const;
/*
* From Java
*/
//string substring(int start, int stop) const;
/*
* From Java
*/
char get_char_at(int index) const;
/*
* From Java
*/
int get_length() const;
friend bool strings_equal(const char* s1, const string& s2) {
if ((s1 == null) && (&s2 == null)) {
return true;
} else if ((s1 == null) || (&s2 == null)) {
return false;
} else {
return strcmp(s1, s2.ptr->array) == 0;
}
}
friend bool strings_equal(const string& s1, const char* s2) {
if ((&s1 == null) && (s2 == null)) {
return true;
} else if ((&s1 == null) || (s2 == null)) {
return false;
} else {
return (0 == strcmp(s1.ptr->array, s2));
}
}
friend bool strings_equal(const string& s1, const string& s2) {
if ((&s1 == null) && (&s2 == null)) {
return true;
} else if ((&s1 == null) || (&s2 == null)) {
return false;
} else {
return (0 == strcmp(s1.ptr->array, s2.ptr->array));
}
}
};
///
/// NOTE: const string& is used rather
/// than string, because the former
/// is more efficient
///
extern string substring(const string& s, int start, int stop);
extern string quoted(const string& s);
extern string reversed(const string& s);
extern string capitalised(const string& s);
extern int index_of(const string& s, const string& key);
#endif /* ALREADY_INCLUDED_STRING_HH */
| Back |