Add minimal version of class Fl_String

This class will be used in fl_input_str() and fl_password_str().

Todo: add missing documentation ...
This commit is contained in:
Albrecht Schlosser 2021-12-04 12:28:42 +01:00
parent 0f72957a24
commit 2404656266
4 changed files with 275 additions and 0 deletions

114
FL/Fl_String.H Normal file
View File

@ -0,0 +1,114 @@
//
// Basic Fl_String header for the Fast Light Tool Kit (FLTK).
//
// Copyright 2021 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// https://www.fltk.org/COPYING.php
//
// Please see the following page on how to report bugs and issues:
//
// https://www.fltk.org/bugs.php
//
#ifndef _FL_FL_STRING_H_
#define _FL_FL_STRING_H_
/** \file FL/Fl_String.H
Basic Fl_String class for FLTK.
*/
/**
Fl_String is the basic string class for FLTK.
In this version Fl_String can be used to store strings, copy strings,
and move strings. There are no string manipulation methods yet.
Fl_String can hold the value of an Fl_Input widget including \e nul bytes
if the constructor Fl_String(const char *str, int size) is used.
Assignment and copy constructors \b copy the string value such that the
source string can be freed immediately after the assignment.
The string value() can be an empty string \c "" or \c NULL.
If value() is not \c NULL it is guaranteed that the string is terminated by
a trailing \c nul byte even if the string contains embedded \c nul bytes.
The method size() returns the full string size, whether the string contains
embedded \c nul bytes or not. The special method slen() returns 0 if value()
is \c NULL, otherwise the same as \c strlen() would do.
Examples:
\code
Fl_String np(NULL);
printf(" np : value = %p, size = %d, slen = %d\n", np.value(), np.size(), np.slen());
Fl_String empty("");
printf(" empty : value = %p, size = %d\n", empty.value(), empty.size());
Fl_String fltk("FLTK");
Fl_Input i(0, 0, 0, 0);
i.value("abc\0def", 7);
Fl_String str(i.value(), i.size());
printf(" str : strlen = %lu, size = %d, capacity = %d\n",
strlen(str.value()), str.size(), str.capacity());
Output:
np : value = (nil), size = 0, slen = 0
empty : value = 0x562840befbf0, size = 0
str : strlen = 3, size = 7, capacity = 15
\endcode
\since 1.4.0
\todo Complete documentation of class Fl_String
*/
class Fl_String {
private:
int size_;
char *value_;
int capacity_;
public:
Fl_String();
Fl_String(const char *str);
Fl_String(const char *str, int size);
// copy constructor
Fl_String(const Fl_String &in);
// copy assignment operator
Fl_String& operator=(const Fl_String &in);
// assignment operator for 'const char *'
Fl_String& operator=(const char *in);
virtual ~Fl_String();
private:
void init();
void alloc_buf(int size);
void release();
public:
void value(const char *str);
void value(const char *str, int slen);
const char *value() const { return value_; }
int size() const { return size_; }
int slen() const;
int capacity() const;
// ================================== DEBUG ==================================
void debug(const char *info) const; // output string info
void hexdump(const char *info) const; // output info + hexdump
}; // class Fl_String
#endif // _FL_FL_STRING_H_

View File

@ -78,6 +78,7 @@ set (CPPFILES
Fl_Single_Window.cxx
Fl_Slider.cxx
Fl_Spinner.cxx
Fl_String.cxx
Fl_Sys_Menu_Bar.cxx
Fl_System_Driver.cxx
Fl_Table.cxx

159
src/Fl_String.cxx Normal file
View File

@ -0,0 +1,159 @@
//
// Basic Fl_String class for the Fast Light Tool Kit (FLTK).
//
// Copyright 2021 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// https://www.fltk.org/COPYING.php
//
// Please see the following page on how to report bugs and issues:
//
// https://www.fltk.org/bugs.php
//
#include <FL/Fl_String.H>
#include <stdio.h>
#include <string.h>
/** \file src/Fl_String.cxx
Basic Fl_String class for FLTK.
*/
static int string_count;
Fl_String::Fl_String() {
string_count++;
init();
// debug("created ()");
}
Fl_String::Fl_String(const char *str) {
string_count++;
init();
value(str);
// debug("created (str)");
}
Fl_String::Fl_String(const char *str, int size) {
string_count++;
init();
value(str, size);
// debug("created (str, size)");
}
void Fl_String::init() {
size_ = 0;
value_ = 0;
capacity_ = 0;
}
// copy constructor
Fl_String::Fl_String(const Fl_String &in) {
string_count++;
init();
value(in.value(), in.size());
// debug("copied (c'tor)");
}
// copy assignment operator
Fl_String& Fl_String::operator=(const Fl_String &in) {
if (this == &in)
return *this;
value(in.value(), in.size());
// debug("copy assigned");
return *this;
}
// assignment operator for 'const char *'
Fl_String& Fl_String::operator=(const char *in) {
value(in);
// debug("*STRING* assigned");
return *this;
}
Fl_String::~Fl_String() {
string_count--;
// debug("~Fl_String()");
delete[] value_;
}
void Fl_String::alloc_buf(int size) {
if (size < 0)
return;
if (size > 0 && size <= capacity_)
return;
if (capacity_ > 0)
return;
int new_size = (size + 1 + 15) & (~15); // round upwards
char *new_value = new char[new_size];
capacity_ = new_size - 1;
size_ = 0;
delete[] value_;
value_ = new_value;
}
void Fl_String::value(const char *str) {
value(str, str ? strlen(str) : 0);
}
int Fl_String::slen() const {
if (!value_) return 0;
return (int)strlen(value_);
}
void Fl_String::value(const char *str, int len) {
if (str) {
alloc_buf(len);
size_ = len;
memcpy(value_, str, size_);
value_[size_] = '\0';
} else { // str == NULL
size_ = 0; // ignore len !
delete[] value_; // free buffer
value_ = NULL; // set null pointer (!)
capacity_ = 0; // reset capacity
}
}
int Fl_String::capacity() const {
return capacity_; // > 0 ? capacity_ - 1 : capacity_;
}
void Fl_String::release() {
delete[] value_;
value_ = 0;
size_ = 0;
capacity_ = 0;
}
// ============================= DEBUG =============================
static const char fl_string_debug = 0;
void Fl_String::debug(const char *info) const {
if (fl_string_debug) {
printf("Fl_String[%2d] '%-20s': %p, value = %p (%d/%d): '%s'.\n",
string_count, info, this, value_, size_, capacity_, value_);
}
}
void Fl_String::hexdump(const char *info) const {
if (fl_string_debug) {
debug(info);
for (int i = 0; i < size_; i++) {
if ((i & 15) == 0) {
if (i > 0) printf("\n");
printf(" [%04x %4d] ", i, i);
} else if ((i & 3) == 0)
printf(" ");
printf(" %02x", (unsigned char)value_[i]);
}
printf("\n");
}
}

View File

@ -80,6 +80,7 @@ CPPFILES = \
Fl_Single_Window.cxx \
Fl_Slider.cxx \
Fl_Spinner.cxx \
Fl_String.cxx \
Fl_Sys_Menu_Bar.cxx \
Fl_System_Driver.cxx \
Fl_Table.cxx \