summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FL/Fl_String.H114
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/Fl_String.cxx159
-rw-r--r--src/Makefile1
4 files changed, 275 insertions, 0 deletions
diff --git a/FL/Fl_String.H b/FL/Fl_String.H
new file mode 100644
index 000000000..471178cd6
--- /dev/null
+++ b/FL/Fl_String.H
@@ -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_
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3c00f0da9..aa74b6c7d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -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
diff --git a/src/Fl_String.cxx b/src/Fl_String.cxx
new file mode 100644
index 000000000..c4417523c
--- /dev/null
+++ b/src/Fl_String.cxx
@@ -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");
+ }
+}
diff --git a/src/Makefile b/src/Makefile
index 0d27e8c61..a31788929 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -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 \