📄 string.cpp
字号:
//-------------------------------------------------------------------
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Revisions.....:
//===================================================================
#include <stdafx.h> // Precompiled headers.
#include <copyright.h>
#include <kernel/basic/string.h>
#include <kernel/basic/macros.h>
#include <kernel/system/stdlib.h>
#include <kernel/system/stdio.h>
#include <kernel/system/math.h>
#include <kernel/system/iostream.h>
#include <kernel/system/ctype.h>
//-------------------------------------------------------------------
// Static stuff (file scope).
//===================================================================
//-------------------------------------------------------------------
// Method........: StaticCopy
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Copies n bytes and null-terminates.
// Comments......:
// Revisions.....:
//===================================================================
static void
StaticCopy(const char *source, char *destination, int n) {
if (source == destination) {
destination[n] = '\0';
return;
}
while (--n >= 0)
*destination++ = *source++;
*destination = '\0';
}
//-------------------------------------------------------------------
// Methods for class String.
//===================================================================
//-------------------------------------------------------------------
// Method........: Constructor
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
String::String() {
representation_ = new Representation();
}
//-------------------------------------------------------------------
// Method........: Constructor
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
String::String(const char *buffer) {
// Create a new representation object.
representation_ = new Representation();
// Check to avoid trouble.
if (buffer == NULL)
buffer = "";
// Allocate buffer.
representation_->size_ = strlen(buffer) + 1;
representation_->buffer_ = new char[representation_->size_];
// Copy the buffer.
strcpy(representation_->buffer_, buffer);
}
//-------------------------------------------------------------------
// Method........: Constructor
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
String::String(const String &in) {
// Share the input string's representation object. This makes assignments cheap!
in.representation_->reference_count_++;
representation_ = in.representation_;
}
//-------------------------------------------------------------------
// Method........: Constructor
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
String::String(char c, int length) {
if (length < 0)
length = 0;
// Create a buffer of the specified length.
representation_ = new Representation();
representation_->size_ = length + 1;
representation_->buffer_ = new char[representation_->size_];
int i;
// Fill the buffer with the specified character.
for (i = 0; i < length; i++)
representation_->buffer_[i] = c;
representation_->buffer_[length] = '\0';
}
//-------------------------------------------------------------------
// Method........: Destructor
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
String::~String() {
// Is this the last string using this representation object?
if (representation_ && --representation_->reference_count_ == 0) {
delete [] representation_->buffer_;
delete representation_;
}
}
//-------------------------------------------------------------------
// Method........: Reserve
// Author........: Aleksander 豩rn
// Date..........: 980703
// Description...: Reserves space so that allocations can be avoided.
// Comments......: Intended for expert use only.
//
// Note that the following won't work as intended:
//
// String s;
// s.Reserve(1000);
// s = "f = ";
// s += "(w + x)";
// s += "(x + y)";
// s += "(y + z)";
// ...
//
// What happens is that the reserved buffer gets
// scrapped in the third line by the assignment
// operator '='! To achieve the intended effect of
// Reserve, do the following instead:
//
// String s;
// s.Reserve(1000);
// s += "f = ";
// s += "(w + x)";
// s += "(x + y)";
// s += "(y + z)";
// ...
//
// Consider more optimal reallocation.
// Revisions.....:
//===================================================================
bool
String::Reserve(int length) {
if (length < 0)
length = 0;
if (representation_ == NULL)
representation_ = new Representation();
// Already space enough?
if (representation_->size_ >= length + 1)
return true;
// Check current reference count, disconnect if needed.
if (representation_->reference_count_ > 1) {
representation_->reference_count_--;
char *buffer = representation_->buffer_;
representation_ = new Representation();
representation_->size_ = length + 1;
representation_->buffer_ = new char[representation_->size_];
strcpy(representation_->buffer_, buffer);
}
else {
representation_->size_ = length + 1;
char *newbuffer = new char[representation_->size_];
if (representation_->buffer_ != NULL) {
strcpy(newbuffer, representation_->buffer_);
delete [] representation_->buffer_;
}
else {
strcpy(newbuffer, "");
}
representation_->buffer_ = newbuffer;
}
return true;
}
//-------------------------------------------------------------------
// Method........: Shrink
// Author........: Aleksander 豩rn
// Date..........: 980703
// Description...:
// Comments......: Intended for expert use only, in conjunction with
// the Reserve method.
//
// Consider more optimal reallocation.
// Revisions.....:
//===================================================================
bool
String::Shrink() {
int length = GetLength();
// Already shrunk to a minimum?
if (representation_ == NULL || representation_->buffer_ == NULL || representation_->size_ == length + 1)
return true;
// Check current reference count, disconnect if needed.
if (representation_->reference_count_ > 1) {
representation_->reference_count_--;
char *buffer = representation_->buffer_;
representation_ = new Representation();
representation_->size_ = length + 1;
representation_->buffer_ = new char[representation_->size_];
strcpy(representation_->buffer_, buffer);
}
else {
representation_->size_ = length + 1;
char *newbuffer = new char[representation_->size_];
strcpy(newbuffer, representation_->buffer_);
delete [] representation_->buffer_;
representation_->buffer_ = newbuffer;
}
return true;
}
//-------------------------------------------------------------------
// Method........: operator =
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....: A
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -