remove old unused source files

This commit is contained in:
Cr4sh 2017-01-16 06:06:18 +03:00
parent 0e09dfe1b2
commit 7cf24f5370
28 changed files with 0 additions and 20310 deletions

View File

@ -1,28 +0,0 @@
Copyright (c) 2014, Paul Hsieh
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of bstrlib nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,34 +0,0 @@
The Better String Library
The Better String Library is an abstraction of a string data type which is
superior to the C library char buffer string type, or C++'s std::string.
Among the features achieved are:
- Substantial mitigation of buffer overflow/overrun problems and other
failures that result from erroneous usage of the common C string
library functions
- Significantly simplified string manipulation
- High performance interoperability with other source/libraries which
expect '\0' terminated char buffers
- Improved overall performance of common string operations
- Functional equivalency with other more modern languages
The library is totally stand alone, portable (known to work with gcc/g++,
MSVC++, Intel C++, WATCOM C/C++, Turbo C, Borland C++, IBM's native CC
compiler on Windows, Linux and Mac OS X), high performance, easy to use and
is not part of some other collection of data structures. Even the file I/O
functions are totally abstracted (so that other stream-like mechanisms, like
sockets, can be used.) Nevertheless, it is adequate as a complete
replacement of the C string library for string manipulation in any C program.
The library includes a robust C++ wrapper that uses overloaded operators,
rich constructors, exceptions, stream I/O and STL to make the CBString
struct a natural and powerful string abstraction with more functionality and
higher performance than std::string.
Bstrlib is stable, well tested and suitable for any software production
environment.

View File

@ -1,82 +0,0 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2015, and is covered by the BSD open source
* license. Refer to the accompanying documentation for details on usage and
* license.
*/
/*
* bsafe.c
*
* This is an optional module that can be used to help enforce a safety
* standard based on pervasive usage of bstrlib. This file is not necessarily
* portable, however, it has been tested to work correctly with Intel's C/C++
* compiler, WATCOM C/C++ v11.x and Microsoft Visual C++.
*/
#include <stdio.h>
#include <stdlib.h>
#include "bsafe.h"
static int bsafeShouldExit = 1;
char * strcpy (char *dst, const char *src);
char * strcat (char *dst, const char *src);
char * strcpy (char *dst, const char *src) {
(void) dst;
(void) src;
fprintf (stderr, "bsafe error: strcpy() is not safe, use bstrcpy instead.\n");
if (bsafeShouldExit) exit (-1);
return NULL;
}
char * strcat (char *dst, const char *src) {
(void) dst;
(void) src;
fprintf (stderr, "bsafe error: strcat() is not safe, use bstrcat instead.\n");
if (bsafeShouldExit) exit (-1);
return NULL;
}
#if !defined (__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310))
char * (gets) (char * buf) {
(void) buf;
fprintf (stderr, "bsafe error: gets() is not safe, use bgets.\n");
if (bsafeShouldExit) exit (-1);
return NULL;
}
#endif
char * (strncpy) (char *dst, const char *src, size_t n) {
(void) dst;
(void) src;
(void) n;
fprintf (stderr, "bsafe error: strncpy() is not safe, use bmidstr instead.\n");
if (bsafeShouldExit) exit (-1);
return NULL;
}
char * (strncat) (char *dst, const char *src, size_t n) {
(void) dst;
(void) src;
(void) n;
fprintf (stderr, "bsafe error: strncat() is not safe, use bstrcat then btrunc\n\tor cstr2tbstr, btrunc then bstrcat instead.\n");
if (bsafeShouldExit) exit (-1);
return NULL;
}
char * (strtok) (char *s1, const char *s2) {
(void) s1;
(void) s2;
fprintf (stderr, "bsafe error: strtok() is not safe, use bsplit or bsplits instead.\n");
if (bsafeShouldExit) exit (-1);
return NULL;
}
char * (strdup) (const char *s) {
(void) s;
fprintf (stderr, "bsafe error: strdup() is not safe, use bstrcpy.\n");
if (bsafeShouldExit) exit (-1);
return NULL;
}

View File

@ -1,43 +0,0 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2004, and is covered by the BSD open source
* license. Refer to the accompanying documentation for details on usage and
* license.
*/
/*
* bsafe.h
*
* This is an optional module that can be used to help enforce a safety
* standard based on pervasive usage of bstrlib. This file is not necessarily
* portable, however, it has been tested to work correctly with Intel's C/C++
* compiler, WATCOM C/C++ v11.x and Microsoft Visual C++.
*/
#ifndef BSTRLIB_BSAFE_INCLUDE
#define BSTRLIB_BSAFE_INCLUDE
#ifdef __cplusplus
extern "C" {
#endif
#if !defined (__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310))
/* This is caught in the linker, so its not necessary for gcc. */
extern char * (gets) (char * buf);
#endif
extern char * (strncpy) (char *dst, const char *src, size_t n);
extern char * (strncat) (char *dst, const char *src, size_t n);
extern char * (strtok) (char *s1, const char *s2);
extern char * (strdup) (const char *s);
#undef strcpy
#undef strcat
#define strcpy(a,b) bsafe_strcpy(a,b)
#define strcat(a,b) bsafe_strcat(a,b)
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,115 +0,0 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2015, and is covered by the BSD open source
* license and the GPL. Refer to the accompanying documentation for details
* on usage and license.
*/
/*
* bstraux.h
*
* This file is not a necessary part of the core bstring library itself, but
* is just an auxilliary module which includes miscellaneous or trivial
* functions.
*/
#ifndef BSTRAUX_INCLUDE
#define BSTRAUX_INCLUDE
#include <time.h>
#include "bstrlib.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Safety mechanisms */
#define bstrDeclare(b) bstring (b) = NULL;
#define bstrFree(b) {if ((b) != NULL && (b)->slen >= 0 && (b)->mlen >= (b)->slen) { bdestroy (b); (b) = NULL; }}
/* Backward compatibilty with previous versions of Bstrlib */
#if !defined(BSTRLIB_REDUCE_NAMESPACE_POLLUTION)
#define bAssign(a,b) ((bassign)((a), (b)))
#define bSubs(b,pos,len,a,c) ((breplace)((b),(pos),(len),(a),(unsigned char)(c)))
#define bStrchr(b,c) ((bstrchr)((b), (c)))
#define bStrchrFast(b,c) ((bstrchr)((b), (c)))
#define bCatCstr(b,s) ((bcatcstr)((b), (s)))
#define bCatBlk(b,s,len) ((bcatblk)((b),(s),(len)))
#define bCatStatic(b,s) bcatStatic(b,s)
#define bTrunc(b,n) ((btrunc)((b), (n)))
#define bReplaceAll(b,find,repl,pos) ((bfindreplace)((b),(find),(repl),(pos)))
#define bUppercase(b) ((btoupper)(b))
#define bLowercase(b) ((btolower)(b))
#define bCaselessCmp(a,b) ((bstricmp)((a), (b)))
#define bCaselessNCmp(a,b,n) ((bstrnicmp)((a), (b), (n)))
#define bBase64Decode(b) (bBase64DecodeEx ((b), NULL))
#define bUuDecode(b) (bUuDecodeEx ((b), NULL))
#endif
/* Unusual functions */
extern struct bStream * bsFromBstr (const_bstring b);
extern bstring bTail (bstring b, int n);
extern bstring bHead (bstring b, int n);
extern int bSetCstrChar (bstring a, int pos, char c);
extern int bSetChar (bstring b, int pos, char c);
extern int bFill (bstring a, char c, int len);
extern int bReplicate (bstring b, int n);
extern int bReverse (bstring b);
extern int bInsertChrs (bstring b, int pos, int len, unsigned char c, unsigned char fill);
extern bstring bStrfTime (const char * fmt, const struct tm * timeptr);
#define bAscTime(t) (bStrfTime ("%c\n", (t)))
#define bCTime(t) ((t) ? bAscTime (localtime (t)) : NULL)
/* Spacing formatting */
extern int bJustifyLeft (bstring b, int space);
extern int bJustifyRight (bstring b, int width, int space);
extern int bJustifyMargin (bstring b, int width, int space);
extern int bJustifyCenter (bstring b, int width, int space);
/* Esoteric standards specific functions */
extern char * bStr2NetStr (const_bstring b);
extern bstring bNetStr2Bstr (const char * buf);
extern bstring bBase64Encode (const_bstring b);
extern bstring bBase64DecodeEx (const_bstring b, int * boolTruncError);
extern struct bStream * bsUuDecode (struct bStream * sInp, int * badlines);
extern bstring bUuDecodeEx (const_bstring src, int * badlines);
extern bstring bUuEncode (const_bstring src);
extern bstring bYEncode (const_bstring src);
extern bstring bYDecode (const_bstring src);
extern int bSGMLEncode (bstring b);
/* Writable stream */
typedef int (* bNwrite) (const void * buf, size_t elsize, size_t nelem, void * parm);
struct bwriteStream * bwsOpen (bNwrite writeFn, void * parm);
int bwsWriteBstr (struct bwriteStream * stream, const_bstring b);
int bwsWriteBlk (struct bwriteStream * stream, void * blk, int len);
int bwsWriteFlush (struct bwriteStream * stream);
int bwsIsEOF (const struct bwriteStream * stream);
int bwsBuffLength (struct bwriteStream * stream, int sz);
void * bwsClose (struct bwriteStream * stream);
/* Security functions */
#define bSecureDestroy(b) { \
bstring bstr__tmp = (b); \
if (bstr__tmp && bstr__tmp->mlen > 0 && bstr__tmp->data) { \
(void) memset (bstr__tmp->data, 0, (size_t) bstr__tmp->mlen); \
bdestroy (bstr__tmp); \
} \
}
#define bSecureWriteProtect(t) { \
if ((t).mlen >= 0) { \
if ((t).mlen > (t).slen)) { \
(void) memset ((t).data + (t).slen, 0, (size_t) (t).mlen - (t).slen); \
} \
(t).mlen = -1; \
} \
}
extern bstring bSecureInput (int maxlen, int termchar,
bNgetc vgetchar, void * vgcCtx);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,316 +0,0 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2015, and is covered by the BSD open source
* license and the GPL. Refer to the accompanying documentation for details
* on usage and license.
*/
/*
* bstrlib.h
*
* This file is the interface for the core bstring functions.
*/
#ifndef BSTRLIB_INCLUDE
#define BSTRLIB_INCLUDE
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP)
# if defined (__TURBOC__) && !defined (__BORLANDC__)
# define BSTRLIB_NOVSNP
# endif
#endif
#define BSTR_ERR (-1)
#define BSTR_OK (0)
#define BSTR_BS_BUFF_LENGTH_GET (0)
typedef struct tagbstring * bstring;
typedef const struct tagbstring * const_bstring;
/* Copy functions */
#define cstr2bstr bfromcstr
extern bstring bfromcstr (const char * str);
extern bstring bfromcstralloc (int mlen, const char * str);
extern bstring bfromcstrrangealloc (int minl, int maxl, const char* str);
extern bstring blk2bstr (const void * blk, int len);
extern char * bstr2cstr (const_bstring s, char z);
extern int bcstrfree (char * s);
extern bstring bstrcpy (const_bstring b1);
extern int bassign (bstring a, const_bstring b);
extern int bassignmidstr (bstring a, const_bstring b, int left, int len);
extern int bassigncstr (bstring a, const char * str);
extern int bassignblk (bstring a, const void * s, int len);
/* Destroy function */
extern int bdestroy (bstring b);
/* Space allocation hinting functions */
extern int balloc (bstring s, int len);
extern int ballocmin (bstring b, int len);
/* Substring extraction */
extern bstring bmidstr (const_bstring b, int left, int len);
/* Various standard manipulations */
extern int bconcat (bstring b0, const_bstring b1);
extern int bconchar (bstring b0, char c);
extern int bcatcstr (bstring b, const char * s);
extern int bcatblk (bstring b, const void * s, int len);
extern int binsert (bstring s1, int pos, const_bstring s2, unsigned char fill);
extern int binsertblk (bstring s1, int pos, const void * s2, int len, unsigned char fill);
extern int binsertch (bstring s1, int pos, int len, unsigned char fill);
extern int breplace (bstring b1, int pos, int len, const_bstring b2, unsigned char fill);
extern int bdelete (bstring s1, int pos, int len);
extern int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill);
extern int btrunc (bstring b, int n);
/* Scan/search functions */
extern int bstricmp (const_bstring b0, const_bstring b1);
extern int bstrnicmp (const_bstring b0, const_bstring b1, int n);
extern int biseqcaseless (const_bstring b0, const_bstring b1);
extern int biseqcaselessblk (const_bstring b, const void * blk, int len);
extern int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len);
extern int biseq (const_bstring b0, const_bstring b1);
extern int biseqblk (const_bstring b, const void * blk, int len);
extern int bisstemeqblk (const_bstring b0, const void * blk, int len);
extern int biseqcstr (const_bstring b, const char * s);
extern int biseqcstrcaseless (const_bstring b, const char * s);
extern int bstrcmp (const_bstring b0, const_bstring b1);
extern int bstrncmp (const_bstring b0, const_bstring b1, int n);
extern int binstr (const_bstring s1, int pos, const_bstring s2);
extern int binstrr (const_bstring s1, int pos, const_bstring s2);
extern int binstrcaseless (const_bstring s1, int pos, const_bstring s2);
extern int binstrrcaseless (const_bstring s1, int pos, const_bstring s2);
extern int bstrchrp (const_bstring b, int c, int pos);
extern int bstrrchrp (const_bstring b, int c, int pos);
#define bstrchr(b,c) bstrchrp ((b), (c), 0)
#define bstrrchr(b,c) bstrrchrp ((b), (c), blength(b)-1)
extern int binchr (const_bstring b0, int pos, const_bstring b1);
extern int binchrr (const_bstring b0, int pos, const_bstring b1);
extern int bninchr (const_bstring b0, int pos, const_bstring b1);
extern int bninchrr (const_bstring b0, int pos, const_bstring b1);
extern int bfindreplace (bstring b, const_bstring find, const_bstring repl, int pos);
extern int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, int pos);
/* List of string container functions */
struct bstrList {
int qty, mlen;
bstring * entry;
};
extern struct bstrList * bstrListCreate (void);
extern int bstrListDestroy (struct bstrList * sl);
extern int bstrListAlloc (struct bstrList * sl, int msz);
extern int bstrListAllocMin (struct bstrList * sl, int msz);
/* String split and join functions */
extern struct bstrList * bsplit (const_bstring str, unsigned char splitChar);
extern struct bstrList * bsplits (const_bstring str, const_bstring splitStr);
extern struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr);
extern bstring bjoin (const struct bstrList * bl, const_bstring sep);
extern bstring bjoinblk (const struct bstrList * bl, const void * s, int len);
extern int bsplitcb (const_bstring str, unsigned char splitChar, int pos,
int (* cb) (void * parm, int ofs, int len), void * parm);
extern int bsplitscb (const_bstring str, const_bstring splitStr, int pos,
int (* cb) (void * parm, int ofs, int len), void * parm);
extern int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos,
int (* cb) (void * parm, int ofs, int len), void * parm);
/* Miscellaneous functions */
extern int bpattern (bstring b, int len);
extern int btoupper (bstring b);
extern int btolower (bstring b);
extern int bltrimws (bstring b);
extern int brtrimws (bstring b);
extern int btrimws (bstring b);
#if !defined (BSTRLIB_NOVSNP)
extern bstring bformat (const char * fmt, ...);
extern int bformata (bstring b, const char * fmt, ...);
extern int bassignformat (bstring b, const char * fmt, ...);
extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist);
#define bvformata(ret, b, fmt, lastarg) { \
bstring bstrtmp_b = (b); \
const char * bstrtmp_fmt = (fmt); \
int bstrtmp_r = BSTR_ERR, bstrtmp_sz = 16; \
for (;;) { \
va_list bstrtmp_arglist; \
va_start (bstrtmp_arglist, lastarg); \
bstrtmp_r = bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \
va_end (bstrtmp_arglist); \
if (bstrtmp_r >= 0) { /* Everything went ok */ \
bstrtmp_r = BSTR_OK; \
break; \
} else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \
bstrtmp_r = BSTR_ERR; \
break; \
} \
bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \
} \
ret = bstrtmp_r; \
}
#endif
typedef int (*bNgetc) (void *parm);
typedef size_t (* bNread) (void *buff, size_t elsize, size_t nelem, void *parm);
/* Input functions */
extern bstring bgets (bNgetc getcPtr, void * parm, char terminator);
extern bstring bread (bNread readPtr, void * parm);
extern int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator);
extern int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator);
extern int breada (bstring b, bNread readPtr, void * parm);
/* Stream functions */
extern struct bStream * bsopen (bNread readPtr, void * parm);
extern void * bsclose (struct bStream * s);
extern int bsbufflength (struct bStream * s, int sz);
extern int bsreadln (bstring b, struct bStream * s, char terminator);
extern int bsreadlns (bstring r, struct bStream * s, const_bstring term);
extern int bsread (bstring b, struct bStream * s, int n);
extern int bsreadlna (bstring b, struct bStream * s, char terminator);
extern int bsreadlnsa (bstring r, struct bStream * s, const_bstring term);
extern int bsreada (bstring b, struct bStream * s, int n);
extern int bsunread (struct bStream * s, const_bstring b);
extern int bspeek (bstring r, const struct bStream * s);
extern int bssplitscb (struct bStream * s, const_bstring splitStr,
int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
extern int bssplitstrcb (struct bStream * s, const_bstring splitStr,
int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
extern int bseof (const struct bStream * s);
struct tagbstring {
int mlen;
int slen;
unsigned char * data;
};
/* Accessor macros */
#define blengthe(b, e) (((b) == (void *)0 || (b)->slen < 0) ? (int)(e) : ((b)->slen))
#define blength(b) (blengthe ((b), 0))
#define bdataofse(b, o, e) (((b) == (void *)0 || (b)->data == (void*)0) ? (char *)(e) : ((char *)(b)->data) + (o))
#define bdataofs(b, o) (bdataofse ((b), (o), (void *)0))
#define bdatae(b, e) (bdataofse (b, 0, e))
#define bdata(b) (bdataofs (b, 0))
#define bchare(b, p, e) ((((unsigned)(p)) < (unsigned)blength(b)) ? ((b)->data[(p)]) : (e))
#define bchar(b, p) bchare ((b), (p), '\0')
/* Static constant string initialization macro */
#define bsStaticMlen(q,m) {(m), (int) sizeof(q)-1, (unsigned char *) ("" q "")}
#if defined(_MSC_VER)
# define bsStatic(q) bsStaticMlen(q,-32)
#endif
#ifndef bsStatic
# define bsStatic(q) bsStaticMlen(q,-__LINE__)
#endif
/* Static constant block parameter pair */
#define bsStaticBlkParms(q) ((void *)("" q "")), ((int) sizeof(q)-1)
#define bcatStatic(b,s) ((bcatblk)((b), bsStaticBlkParms(s)))
#define bfromStatic(s) ((blk2bstr)(bsStaticBlkParms(s)))
#define bassignStatic(b,s) ((bassignblk)((b), bsStaticBlkParms(s)))
#define binsertStatic(b,p,s,f) ((binsertblk)((b), (p), bsStaticBlkParms(s), (f)))
#define bjoinStatic(b,s) ((bjoinblk)((b), bsStaticBlkParms(s)))
#define biseqStatic(b,s) ((biseqblk)((b), bsStaticBlkParms(s)))
#define bisstemeqStatic(b,s) ((bisstemeqblk)((b), bsStaticBlkParms(s)))
#define biseqcaselessStatic(b,s) ((biseqcaselessblk)((b), bsStaticBlkParms(s)))
#define bisstemeqcaselessStatic(b,s) ((bisstemeqcaselessblk)((b), bsStaticBlkParms(s)))
/* Reference building macros */
#define cstr2tbstr btfromcstr
#define btfromcstr(t,s) { \
(t).data = (unsigned char *) (s); \
(t).slen = ((t).data) ? ((int) (strlen) ((char *)(t).data)) : 0; \
(t).mlen = -1; \
}
#define blk2tbstr(t,s,l) { \
(t).data = (unsigned char *) (s); \
(t).slen = l; \
(t).mlen = -1; \
}
#define btfromblk(t,s,l) blk2tbstr(t,s,l)
#define bmid2tbstr(t,b,p,l) { \
const_bstring bstrtmp_s = (b); \
if (bstrtmp_s && bstrtmp_s->data && bstrtmp_s->slen >= 0) { \
int bstrtmp_left = (p); \
int bstrtmp_len = (l); \
if (bstrtmp_left < 0) { \
bstrtmp_len += bstrtmp_left; \
bstrtmp_left = 0; \
} \
if (bstrtmp_len > bstrtmp_s->slen - bstrtmp_left) \
bstrtmp_len = bstrtmp_s->slen - bstrtmp_left; \
if (bstrtmp_len <= 0) { \
(t).data = (unsigned char *)""; \
(t).slen = 0; \
} else { \
(t).data = bstrtmp_s->data + bstrtmp_left; \
(t).slen = bstrtmp_len; \
} \
} else { \
(t).data = (unsigned char *)""; \
(t).slen = 0; \
} \
(t).mlen = -__LINE__; \
}
#define btfromblkltrimws(t,s,l) { \
int bstrtmp_idx = 0, bstrtmp_len = (l); \
unsigned char * bstrtmp_s = (s); \
if (bstrtmp_s && bstrtmp_len >= 0) { \
for (; bstrtmp_idx < bstrtmp_len; bstrtmp_idx++) { \
if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \
} \
} \
(t).data = bstrtmp_s + bstrtmp_idx; \
(t).slen = bstrtmp_len - bstrtmp_idx; \
(t).mlen = -__LINE__; \
}
#define btfromblkrtrimws(t,s,l) { \
int bstrtmp_len = (l) - 1; \
unsigned char * bstrtmp_s = (s); \
if (bstrtmp_s && bstrtmp_len >= 0) { \
for (; bstrtmp_len >= 0; bstrtmp_len--) { \
if (!isspace (bstrtmp_s[bstrtmp_len])) break; \
} \
} \
(t).data = bstrtmp_s; \
(t).slen = bstrtmp_len + 1; \
(t).mlen = -__LINE__; \
}
#define btfromblktrimws(t,s,l) { \
int bstrtmp_idx = 0, bstrtmp_len = (l) - 1; \
unsigned char * bstrtmp_s = (s); \
if (bstrtmp_s && bstrtmp_len >= 0) { \
for (; bstrtmp_idx <= bstrtmp_len; bstrtmp_idx++) { \
if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \
} \
for (; bstrtmp_len >= bstrtmp_idx; bstrtmp_len--) { \
if (!isspace (bstrtmp_s[bstrtmp_len])) break; \
} \
} \
(t).data = bstrtmp_s + bstrtmp_idx; \
(t).slen = bstrtmp_len + 1 - bstrtmp_idx; \
(t).mlen = -__LINE__; \
}
/* Write protection macros */
#define bwriteprotect(t) { if ((t).mlen >= 0) (t).mlen = -1; }
#define bwriteallow(t) { if ((t).mlen == -1) (t).mlen = (t).slen + ((t).slen == 0); }
#define biswriteprotected(t) ((t).mlen <= 0)
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,449 +0,0 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2015, and is covered by the BSD open source
* license and the GPL. Refer to the accompanying documentation for details
* on usage and license.
*/
/*
* bstrwrap.h
*
* This file is the C++ wrapper for the bstring functions.
*/
#ifndef BSTRWRAP_INCLUDE
#define BSTRWRAP_INCLUDE
/////////////////// Configuration defines //////////////////////////////
// WATCOM C/C++ has broken STL and std::iostream support. If you have
// ported over STLport, then you can #define BSTRLIB_CAN_USE_STL to use
// the CBStringList class.
#if defined(__WATCOMC__)
# if !defined (BSTRLIB_CAN_USE_STL) && !defined (BSTRLIB_CANNOT_USE_STL)
# define BSTRLIB_CANNOT_USE_STL
# endif
# if !defined (BSTRLIB_CAN_USE_IOSTREAM) && !defined (BSTRLIB_CANNOT_USE_IOSTREAM)
# define BSTRLIB_CANNOT_USE_IOSTREAM
# endif
#endif
// By default it assumed that STL has been installed and works for your
// compiler. If this is not the case, then #define BSTRLIB_CANNOT_USE_STL
#if !defined (BSTRLIB_CANNOT_USE_STL) && !defined (BSTRLIB_CAN_USE_STL)
#define BSTRLIB_CAN_USE_STL
#endif
// By default it assumed that std::iostream works well with your compiler.
// If this is not the case, then #define BSTRLIB_CAN_USE_IOSTREAM
#if !defined (BSTRLIB_CANNOT_USE_IOSTREAM) && !defined (BSTRLIB_CAN_USE_IOSTREAM)
#define BSTRLIB_CAN_USE_IOSTREAM
#endif
// By default it is assumed that your compiler can deal with and has enabled
// exception handlling. If this is not the case then you will need to
// #define BSTRLIB_DOESNT_THROW_EXCEPTIONS
#if !defined (BSTRLIB_THROWS_EXCEPTIONS) && !defined (BSTRLIB_DOESNT_THROW_EXCEPTIONS)
#define BSTRLIB_THROWS_EXCEPTIONS
#endif
////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include "bstrlib.h"
#include "../common/ubytearray.h"
#ifdef __cplusplus
#if defined(BSTRLIB_CAN_USE_STL)
#if defined(__WATCOMC__)
#pragma warning 604 10
#pragma warning 595 10
#pragma warning 594 10
#pragma warning 549 10
#endif
#include <vector>
#include <string>
#if defined(__WATCOMC__)
#pragma warning 604 9
#pragma warning 595 9
#pragma warning 594 9
#endif
#endif
namespace Bstrlib {
#ifdef BSTRLIB_THROWS_EXCEPTIONS
#if defined(BSTRLIB_CAN_USE_STL)
struct CBStringException : public std::exception {
private:
std::string msg;
public:
CBStringException (const std::string inmsg) : msg(inmsg) {}
virtual ~CBStringException () throw () {}
virtual const char *what () const throw () { return msg.c_str(); }
};
#else
struct CBStringException {
private:
char * msg;
int needToFree;
public:
CBStringException (const char * inmsg) : needToFree(0) {
if (inmsg) {
msg = (char *) malloc (1 + strlen (inmsg));
if (NULL == msg) msg = "Out of memory";
else {
strcpy (msg, inmsg);
needToFree = 1;
}
} else {
msg = "NULL exception message";
}
}
virtual ~CBStringException () throw () {
if (needToFree) {
free (msg);
needToFree = 0;
msg = NULL;
}
}
virtual const char *what () const throw () { return msg; }
};
#endif
#define bstringThrow(er) {\
CBStringException bstr__cppwrapper_exception ("CBString::" er "");\
throw bstr__cppwrapper_exception;\
}
#else
#define bstringThrow(er) {}
#endif
struct CBString;
#ifdef _MSC_VER
#pragma warning(disable:4512)
#endif
class CBCharWriteProtected {
friend struct CBString;
private:
const struct tagbstring& s;
unsigned int idx;
CBCharWriteProtected (const struct tagbstring& c, int i) : s(c), idx((unsigned int)i) {
if (idx >= (unsigned) s.slen) {
bstringThrow ("character index out of bounds");
}
}
public:
inline char operator = (char c) {
if (s.mlen <= 0) {
bstringThrow ("Write protection error");
} else {
#ifndef BSTRLIB_THROWS_EXCEPTIONS
if (idx >= (unsigned) s.slen) return '\0';
#endif
s.data[idx] = (unsigned char) c;
}
return (char) s.data[idx];
}
inline unsigned char operator = (unsigned char c) {
if (s.mlen <= 0) {
bstringThrow ("Write protection error");
} else {
#ifndef BSTRLIB_THROWS_EXCEPTIONS
if (idx >= (unsigned) s.slen) return '\0';
#endif
s.data[idx] = c;
}
return s.data[idx];
}
inline operator unsigned char () const {
#ifndef BSTRLIB_THROWS_EXCEPTIONS
if (idx >= (unsigned) s.slen) return (unsigned char) '\0';
#endif
return s.data[idx];
}
};
struct CBString : public tagbstring {
// Constructors
CBString ();
CBString (char c);
CBString (unsigned char c);
CBString (const char *s);
CBString (int len, const char *s);
CBString (const CBString& b);
CBString (const tagbstring& x);
CBString (char c, int len);
CBString (const void * blk, int len);
#if defined(BSTRLIB_CAN_USE_STL)
CBString (const struct CBStringList& l);
CBString (const struct CBStringList& l, const CBString& sep);
CBString (const struct CBStringList& l, char sep);
CBString (const struct CBStringList& l, unsigned char sep);
#endif
// Destructor
#if !defined(BSTRLIB_DONT_USE_VIRTUAL_DESTRUCTOR)
virtual
#endif
~CBString ();
// = operator
const CBString& operator = (char c);
const CBString& operator = (unsigned char c);
const CBString& operator = (const char *s);
const CBString& operator = (const CBString& b);
const CBString& operator = (const tagbstring& x);
// += operator
const CBString& operator += (char c);
const CBString& operator += (unsigned char c);
const CBString& operator += (const char *s);
const CBString& operator += (const CBString& b);
const CBString& operator += (const tagbstring& x);
// *= operator
inline const CBString& operator *= (int count) {
this->repeat (count);
return *this;
}
// + operator
const CBString operator + (char c) const;
const CBString operator + (unsigned char c) const;
const CBString operator + (const unsigned char *s) const;
const CBString operator + (const char *s) const;
const CBString operator + (const CBString& b) const;
const CBString operator + (const tagbstring& x) const;
// * operator
inline const CBString operator * (int count) const {
CBString retval (*this);
retval.repeat (count);
return retval;
}
// Comparison operators
bool operator == (const CBString& b) const;
bool operator == (const char * s) const;
bool operator == (const unsigned char * s) const;
bool operator != (const CBString& b) const;
bool operator != (const char * s) const;
bool operator != (const unsigned char * s) const;
bool operator < (const CBString& b) const;
bool operator < (const char * s) const;
bool operator < (const unsigned char * s) const;
bool operator <= (const CBString& b) const;
bool operator <= (const char * s) const;
bool operator <= (const unsigned char * s) const;
bool operator > (const CBString& b) const;
bool operator > (const char * s) const;
bool operator > (const unsigned char * s) const;
bool operator >= (const CBString& b) const;
bool operator >= (const char * s) const;
bool operator >= (const unsigned char * s) const;
// Casts
inline operator const char* () const { return (const char *)data; }
inline operator const unsigned char* () const { return (const unsigned char *)data; }
operator double () const;
operator float () const;
operator int () const;
operator unsigned int () const;
// Accessors
inline int length () const {return slen;}
inline unsigned char character (int i) const {
if (((unsigned) i) >= (unsigned) slen) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("character idx out of bounds");
#else
return '\0';
#endif
}
return data[i];
}
inline unsigned char operator [] (int i) const { return character(i); }
inline CBCharWriteProtected character (int i) {
return CBCharWriteProtected (*this, i);
}
inline CBCharWriteProtected operator [] (int i) { return character(i); }
// Space allocation hint method.
void alloc (int length);
// Search methods.
int caselessEqual (const CBString& b) const;
int caselessCmp (const CBString& b) const;
int find (const CBString& b, int pos = 0) const;
int find (const char * b, int pos = 0) const;
int caselessfind (const CBString& b, int pos = 0) const;
int caselessfind (const char * b, int pos = 0) const;
int find (char c, int pos = 0) const;
int reversefind (const CBString& b, int pos) const;
int reversefind (const char * b, int pos) const;
int caselessreversefind (const CBString& b, int pos) const;
int caselessreversefind (const char * b, int pos) const;
int reversefind (char c, int pos) const;
int findchr (const CBString& b, int pos = 0) const;
int findchr (const char * s, int pos = 0) const;
int reversefindchr (const CBString& b, int pos) const;
int reversefindchr (const char * s, int pos) const;
int nfindchr (const CBString& b, int pos = 0) const;
int nfindchr (const char * b, int pos = 0) const;
int nreversefindchr (const CBString& b, int pos) const;
int nreversefindchr (const char * b, int pos) const;
// Search and substitute methods.
void findreplace (const CBString& find, const CBString& repl, int pos = 0);
void findreplace (const CBString& find, const char * repl, int pos = 0);
void findreplace (const char * find, const CBString& repl, int pos = 0);
void findreplace (const char * find, const char * repl, int pos = 0);
void findreplacecaseless (const CBString& find, const CBString& repl, int pos = 0);
void findreplacecaseless (const CBString& find, const char * repl, int pos = 0);
void findreplacecaseless (const char * find, const CBString& repl, int pos = 0);
void findreplacecaseless (const char * find, const char * repl, int pos = 0);
// Extraction method.
CBString midstr (int left, int len) const;
// Standard manipulation methods.
void setsubstr (int pos, const CBString& b, unsigned char fill = ' ');
void setsubstr (int pos, const char * b, unsigned char fill = ' ');
void insert (int pos, const CBString& b, unsigned char fill = ' ');
void insert (int pos, const char * b, unsigned char fill = ' ');
void insertchrs (int pos, int len, unsigned char fill = ' ');
void replace (int pos, int len, const CBString& b, unsigned char fill = ' ');
void replace (int pos, int len, const char * s, unsigned char fill = ' ');
void remove (int pos, int len);
void trunc (int len);
// Miscellaneous methods.
void format (const char * fmt, ...);
void formata (const char * fmt, ...);
void fill (int length, unsigned char fill = ' ');
void repeat (int count);
void ltrim (const CBString& b = CBString (bsStaticBlkParms (" \t\v\f\r\n")));
void rtrim (const CBString& b = CBString (bsStaticBlkParms (" \t\v\f\r\n")));
inline void trim (const CBString& b = CBString (bsStaticBlkParms (" \t\v\f\r\n"))) {
rtrim (b);
ltrim (b);
}
void toupper ();
void tolower ();
// Write protection methods.
void writeprotect ();
void writeallow ();
inline bool iswriteprotected () const { return mlen <= 0; }
// Join methods.
#if defined(BSTRLIB_CAN_USE_STL)
void join (const struct CBStringList& l);
void join (const struct CBStringList& l, const CBString& sep);
void join (const struct CBStringList& l, char sep);
void join (const struct CBStringList& l, unsigned char sep);
#endif
// CBStream methods
int gets (bNgetc getcPtr, void * parm, char terminator = '\n');
int read (bNread readPtr, void * parm);
// QString compatibility methods
CBString toLocal8Bit() const { return *this; }
bool isEmpty() const { return slen == 0; }
void clear() { *this = ""; }
CBString left(int len) const { return midstr(0, len); }
CBString mid(int pos, int len) const { return midstr(pos, len); }
static CBString fromUtf16(const unsigned short* str) { // Naive implementation assuming that only ASCII part of UCS2 is used
CBString msg; while (*str) { msg += *(char*)str; str++; } return msg;
}
CBString leftJustified(int length) { if (length > slen) { return *this + CBString(' ', length - slen); } return *this; }
};
extern const CBString operator + (const char *a, const CBString& b);
extern const CBString operator + (const unsigned char *a, const CBString& b);
extern const CBString operator + (char c, const CBString& b);
extern const CBString operator + (unsigned char c, const CBString& b);
extern const CBString operator + (const tagbstring& x, const CBString& b);
inline const CBString operator * (int count, const CBString& b) {
CBString retval (b);
retval.repeat (count);
return retval;
}
#if defined(BSTRLIB_CAN_USE_IOSTREAM)
extern std::ostream& operator << (std::ostream& sout, CBString b);
extern std::istream& operator >> (std::istream& sin, CBString& b);
extern std::istream& getline (std::istream& sin, CBString& b, char terminator='\n');
#endif
struct CBStream {
friend struct CBStringList;
private:
struct bStream * m_s;
public:
CBStream (bNread readPtr, void * parm);
~CBStream ();
int buffLengthSet (int sz);
int buffLengthGet ();
int eof () const;
CBString readLine (char terminator);
CBString readLine (const CBString& terminator);
void readLine (CBString& s, char terminator);
void readLine (CBString& s, const CBString& terminator);
void readLineAppend (CBString& s, char terminator);
void readLineAppend (CBString& s, const CBString& terminator);
CBString read ();
CBString& operator >> (CBString& s);
CBString read (int n);
void read (CBString& s);
void read (CBString& s, int n);
void readAppend (CBString& s);
void readAppend (CBString& s, int n);
void unread (const CBString& s);
inline CBStream& operator << (const CBString& s) {
this->unread (s);
return *this;
}
CBString peek () const;
void peek (CBString& s) const;
void peekAppend (CBString& s) const;
};
#if defined(BSTRLIB_CAN_USE_STL)
struct CBStringList : public std::vector<CBString> {
// split a string into a vector of strings.
void split (const CBString& b, unsigned char splitChar);
void split (const CBString& b, const CBString& s);
void splitstr (const CBString& b, const CBString& s);
void split (const CBStream& b, unsigned char splitChar);
void split (const CBStream& b, const CBString& s);
void splitstr (const CBStream& b, const CBString& s);
};
#endif
} // namespace Bstrlib
#if !defined (BSTRLIB_DONT_ASSUME_NAMESPACE)
using namespace Bstrlib;
#endif
#endif
#endif

View File

@ -1,274 +0,0 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2015, and is covered by the BSD open source
* license and the GPL. Refer to the accompanying documentation for details
* on usage and license.
*/
/*
* buniutil.c
*
* This file is not necessarily part of the core bstring library itself, but
* is just an implementation of basic utf8 processing for bstrlib. Note that
* this module is dependent upon bstrlib.c and utf8util.c
*/
#include "bstrlib.h"
#include "buniutil.h"
#define UNICODE__CODE_POINT__REPLACEMENT_CHARACTER (0xFFFDL)
/* int buIsUTF8Content (const_bstring bu)
*
* Scan string and return 1 if its entire contents is entirely UTF8 code
* points. Otherwise return 0.
*/
int buIsUTF8Content (const_bstring bu) {
struct utf8Iterator iter;
if (NULL == bdata (bu)) return 0;
for (utf8IteratorInit (&iter, bu->data, bu->slen);
iter.next < iter.slen;) {
if (0 >= utf8IteratorGetNextCodePoint (&iter, -1)) return 0;
}
return 1;
}
/* int buGetBlkUTF16 (cpUcs2* ucs2, int len, cpUcs4 errCh, const_bstring bu,
* int pos)
*
* Convert a string of UTF8 codepoints (bu) skipping the first pos, into a
* sequence of UTF16 encoded code points. Returns the number of UCS2 16-bit
* words written to the output. No more than len words are written to the
* target array ucs2. If any code point in bu is unparsable, it will be
* translated to errCh.
*/
int buGetBlkUTF16 (/* @out */ cpUcs2* ucs2, int len, cpUcs4 errCh, const_bstring bu, int pos) {
struct tagbstring t;
struct utf8Iterator iter;
cpUcs4 ucs4;
int i, j;
if (!isLegalUnicodeCodePoint (errCh)) errCh = UNICODE__CODE_POINT__REPLACEMENT_CHARACTER;
if (NULL == ucs2 || 0 >= len || NULL == bdata (bu) || 0 > pos) return BSTR_ERR;
for (j=0, i=0; j < bu->slen; j++) {
if (0x80 != (0xC0 & bu->data[j])) {
if (i >= pos) break;
i++;
}
}
t.mlen = -1;
t.data = bu->data + j;
t.slen = bu->slen - j;
utf8IteratorInit (&iter, t.data, t.slen);
ucs4 = BSTR_ERR;
for (i=0; 0 < len && iter.next < iter.slen &&
0 <= (ucs4 = utf8IteratorGetNextCodePoint (&iter, errCh)); i++) {
if (ucs4 < 0x10000) {
*ucs2++ = (cpUcs2) ucs4;
len--;
} else {
if (len < 2) {
*ucs2++ = UNICODE__CODE_POINT__REPLACEMENT_CHARACTER;
len--;
} else {
long y = ucs4 - 0x10000;
ucs2[0] = (cpUcs2) (0xD800 | (y >> 10));
ucs2[1] = (cpUcs2) (0xDC00 | (y & 0x03FF));
len -= 2;
ucs2 += 2;
i++;
}
}
}
while (0 < len) {
*ucs2++ = 0;
len--;
}
utf8IteratorUninit (&iter);
if (0 > ucs4) return BSTR_ERR;
return i;
}
/*
Unicode UTF-8
------- -----
U-00000000 - U-0000007F: 0xxxxxxx
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
UTF-32: U-000000 - U-10FFFF
*/
/* int buAppendBlkUcs4 (bstring b, const cpUcs4* bu, int len, cpUcs4 errCh)
*
* Convert an array of UCS4 code points (bu) to UTF8 codepoints b. Any
* invalid code point is replaced by errCh. If errCh is itself not a
* valid code point, then this translation will halt upon the first error
* and return BSTR_ERR. Otherwise BSTR_OK is returned.
*/
int buAppendBlkUcs4 (bstring b, const cpUcs4* bu, int len, cpUcs4 errCh) {
int i, oldSlen;
if (NULL == bu || NULL == b || 0 > len || 0 > (oldSlen = blengthe (b, -1))) return BSTR_ERR;
if (!isLegalUnicodeCodePoint (errCh)) errCh = ~0;
for (i=0; i < len; i++) {
unsigned char c[6];
cpUcs4 v = bu[i];
if (!isLegalUnicodeCodePoint (v)) {
if (~0 == errCh) {
b->slen = oldSlen;
return BSTR_ERR;
}
v = errCh;
}
if (v < 0x80) {
if (BSTR_OK != bconchar (b, (char) v)) {
b->slen = oldSlen;
return BSTR_ERR;
}
} else if (v < 0x800) {
c[0] = (unsigned char) ( (v >> 6) + 0xc0);
c[1] = (unsigned char) (( v & 0x3f) + 0x80);
if (BSTR_OK != bcatblk (b, c, 2)) {
b->slen = oldSlen;
return BSTR_ERR;
}
} else if (v < 0x10000) {
c[0] = (unsigned char) ( (v >> 12) + 0xe0);
c[1] = (unsigned char) (((v >> 6) & 0x3f) + 0x80);
c[2] = (unsigned char) (( v & 0x3f) + 0x80);
if (BSTR_OK != bcatblk (b, c, 3)) {
b->slen = oldSlen;
return BSTR_ERR;
}
} else
#if 0
if (v < 0x200000)
#endif
{
c[0] = (unsigned char) ( (v >> 18) + 0xf0);
c[1] = (unsigned char) (((v >> 12) & 0x3f) + 0x80);
c[2] = (unsigned char) (((v >> 6) & 0x3f) + 0x80);
c[3] = (unsigned char) (( v & 0x3f) + 0x80);
if (BSTR_OK != bcatblk (b, c, 4)) {
b->slen = oldSlen;
return BSTR_ERR;
}
}
#if 0
else if (v < 0x4000000) {
c[0] = (unsigned char) ( (v >> 24) + 0xf8);
c[1] = (unsigned char) (((v >> 18) & 0x3f) + 0x80);
c[2] = (unsigned char) (((v >> 12) & 0x3f) + 0x80);
c[3] = (unsigned char) (((v >> 6) & 0x3f) + 0x80);
c[4] = (unsigned char) (( v & 0x3f) + 0x80);
if (BSTR_OK != bcatblk (b, c, 5)) {
b->slen = oldSlen;
return BSTR_ERR;
}
} else {
c[0] = (unsigned char) ( (v >> 30) + 0xfc);
c[1] = (unsigned char) (((v >> 24) & 0x3f) + 0x80);
c[2] = (unsigned char) (((v >> 18) & 0x3f) + 0x80);
c[3] = (unsigned char) (((v >> 12) & 0x3f) + 0x80);
c[4] = (unsigned char) (((v >> 6) & 0x3f) + 0x80);
c[5] = (unsigned char) (( v & 0x3f) + 0x80);
if (BSTR_OK != bcatblk (b, c, 6)) {
b->slen = oldSlen;
return BSTR_ERR;
}
}
#endif
}
return BSTR_OK;
}
#define endSwap(cs,mode) ((mode) ? ((((cs) & 0xFF) << 8) | (((cs) >> 8) & 0xFF)) : (cs))
#define TEMP_UCS4_BUFFER_SIZE (64)
/* int buAppendBlkUTF16 (bstring bu, const cpUcs2* utf16, int len,
* cpUcs2* bom, cpUcs4 errCh)
*
* Append an array of UCS2 code points (utf16) to UTF8 codepoints (bu). Any
* invalid code point is replaced by errCh. If errCh is itself not a
* valid code point, then this translation will halt upon the first error
* and return BSTR_ERR. Otherwise BSTR_OK is returned. If a byte order mark
* has been previously read, it may be passed in as bom, otherwise if *bom is
* set to 0, it will be filled in with the BOM as read from the first
* character if it is a BOM.
*/
int buAppendBlkUTF16 (bstring bu, const cpUcs2* utf16, int len, cpUcs2* bom, cpUcs4 errCh) {
cpUcs4 buff[TEMP_UCS4_BUFFER_SIZE];
int cc, i, sm, oldSlen;
if (NULL == bdata(bu) || NULL == utf16 || len < 0) return BSTR_ERR;
if (!isLegalUnicodeCodePoint (errCh)) errCh = ~0;
if (len == 0) return BSTR_OK;
oldSlen = bu->slen;
i = 0;
/* Check for BOM character and select endianess. Also remove the
BOM from the stream, since there is no need for it in a UTF-8 encoding. */
if (bom && (cpUcs2) 0xFFFE == *bom) {
sm = 8;
} else if (bom && (cpUcs2) 0xFEFF == *bom) {
sm = 0;
} else if (utf16[i] == (cpUcs2) 0xFFFE) {
if (bom) *bom = utf16[i];
sm = 8;
i++;
} else if (utf16[i] == (cpUcs2) 0xFEFF) {
if (bom) *bom = utf16[i];
sm = 0;
i++;
} else {
sm = 0; /* Assume local endianness. */
}
cc = 0;
for (;i < len; i++) {
cpUcs4 c, v;
v = endSwap (utf16[i], sm);
if ((v | 0x7FF) == 0xDFFF) { /* Deal with surrogate pairs */
if (v >= 0xDC00 || i >= len) {
ErrMode:;
if (~0 == errCh) {
ErrReturn:;
bu->slen = oldSlen;
return BSTR_ERR;
}
v = errCh;
} else {
i++;
if ((c = endSwap (utf16[i], sm) - 0xDC00) > 0x3FF) goto ErrMode;
v = ((v - 0xD800) << 10) + c + 0x10000;
}
}
buff[cc] = v;
cc++;
if (cc >= TEMP_UCS4_BUFFER_SIZE) {
if (0 > buAppendBlkUcs4 (bu, buff, cc, errCh)) goto ErrReturn;
cc = 0;
}
}
if (cc > 0 && 0 > buAppendBlkUcs4 (bu, buff, cc, errCh)) goto ErrReturn;
return BSTR_OK;
}

View File

@ -1,37 +0,0 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2015, and is covered by the BSD open source
* license and the GPL. Refer to the accompanying documentation for details
* on usage and license.
*/
/*
* buniutil.h
*
* This file is the interface for the buniutil basic "Unicode for bstrings"
* functions. Note that there are dependencies on bstrlib.h and utf8util.h .
*/
#ifndef BSTRLIB_UNICODE_UTILITIES
#define BSTRLIB_UNICODE_UTILITIES
#include "utf8util.h"
#include "bstrlib.h"
#ifdef __cplusplus
extern "C" {
#endif
extern int buIsUTF8Content (const_bstring bu);
extern int buAppendBlkUcs4 (bstring b, const cpUcs4* bu, int len, cpUcs4 errCh);
/* For those unfortunate enough to be stuck supporting UTF16. */
extern int buGetBlkUTF16 (/* @out */ cpUcs2* ucs2, int len, cpUcs4 errCh, const_bstring bu, int pos);
extern int buAppendBlkUTF16 (bstring bu, const cpUcs2* utf16, int len, cpUcs2* bom, cpUcs4 errCh);
#ifdef __cplusplus
}
#endif
#endif /* BSTRLIB_UNICODE_UTILITIES */

View File

@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@ -1,172 +0,0 @@
Better String library Porting Guide
-----------------------------------
by Paul Hsieh
The bstring library is an attempt to provide improved string processing
functionality to the C and C++ language. At the heart of the bstring library
is the management of "bstring"s which are a significant improvement over '\0'
terminated char buffers. See the accompanying documenation file bstrlib.txt
for more information.
===============================================================================
Identifying the Compiler
------------------------
Bstrlib has been tested on the following compilers:
Microsoft Visual C++
Watcom C/C++ (32 bit flat)
Intel's C/C++ compiler (on Windows)
The GNU C/C++ compiler (on Windows/Linux on x86 and PPC64)
Borland C++
Turbo C
There are slight differences in these compilers which requires slight
differences in the implementation of Bstrlib. These are accomodated in the
same sources using #ifdef/#if defined() on compiler specific macros. To
port Bstrlib to a new compiler not listed above, it is recommended that the
same strategy be followed. If you are unaware of the compiler specific
identifying preprocessor macro for your compiler you might find it here:
http://predef.sourceforge.net/precomp.html
Note that Intel C/C++ on Windows sets the Microsoft identifier: _MSC_VER.
16-bit vs. 32-bit vs. 64-bit Systems
------------------------------------
Bstrlib has been architected to deal with strings of length between 0 and
INT_MAX (inclusive). Since the values of int are never higher than size_t
there will be no issue here. Note that on most 64-bit systems int is 32-bit.
Dependency on The C-Library
---------------------------
Bstrlib uses the functions memcpy, memmove, malloc, realloc, free and
vsnprintf. Many free standing C compiler implementations that have a mode in
which the C library is not available will typically not include these
functions which will make porting Bstrlib to it onerous. Bstrlib is not
designed for such bare bones compiler environments. This usually includes
compilers that target ROM environments.
Porting Issues
--------------
Bstrlib has been written completely in ANSI/ISO C and ISO C++, however, there
are still a few porting issues. These are described below.
1. The vsnprintf () function.
Unfortunately, the earlier ANSI/ISO C standards did not include this function.
If the compiler of interest does not support this function then the
BSTRLIB_NOVSNP should be defined via something like:
#if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP)
# if defined (__TURBOC__) || defined (__COMPILERVENDORSPECIFICMACRO__)
# define BSTRLIB_NOVSNP
# endif
#endif
which appears at the top of bstrlib.h. Note that the bformat(a) functions
will not be declared or implemented if the BSTRLIB_NOVSNP macro is set. If
the compiler has renamed vsnprintf() to some other named function, then
search for the definition of the exvsnprintf macro in bstrlib.c file and be
sure its defined appropriately:
#if defined (__COMPILERVENDORSPECIFICMACRO__)
# define exvsnprintf(r,b,n,f,a) {r=__compiler_specific_vsnprintf(b,n,f,a);}
#else
# define exvsnprintf(r,b,n,f,a) {r=vsnprintf(b,n,f,a);}
#endif
Take notice of the return value being captured in the variable r. It is
assumed that r exceeds n if and only if the underlying vsnprintf function has
determined what the true maximal output length would be for output if the
buffer were large enough to hold it. Non-modern implementations must output a
lesser number (the macro can and should be modified to ensure this).
2. Weak C++ compiler.
C++ is a much more complicated language to implement than C. This has lead
to varying quality of compiler implementations. The weaknesses isolated in
the initial ports are inclusion of the Standard Template Library,
std::iostream and exception handling. By default it is assumed that the C++
compiler supports all of these things correctly. If your compiler does not
support one or more of these define the corresponding macro:
BSTRLIB_CANNOT_USE_STL
BSTRLIB_CANNOT_USE_IOSTREAM
BSTRLIB_DOESNT_THROW_EXCEPTIONS
The compiler specific detected macro should be defined at the top of
bstrwrap.h in the Configuration defines section. Note that these disabling
macros can be overrided with the associated enabling macro if a subsequent
version of the compiler gains support. (For example, its possible to rig
up STLport to provide STL support for WATCOM C/C++, so -DBSTRLIB_CAN_USE_STL
can be passed in as a compiler option.)
3. The bsafe module, and reserved words.
The bsafe module is in gross violation of the ANSI/ISO C standard in the
sense that it redefines what could be implemented as reserved words on a
given compiler. The typical problem is that a compiler may inline some of the
functions and thus not be properly overridden by the definitions in the bsafe
module. It is also possible that a compiler may prohibit the redefinitions in
the bsafe module. Compiler specific action will be required to deal with
these situations.
Platform Specific Files
-----------------------
The makefiles for the examples are basically setup of for particular
environments for each platform. In general these makefiles are not portable
and should be constructed as necessary from scratch for each platform.
Testing a port
--------------
To test that a port compiles correctly do the following:
1. Build a sample project that includes the bstrlib, bstraux, bstrwrap, and
bsafe modules.
2. Compile bstest against the bstrlib module.
3. Run bstest and ensure that 0 errors are reported.
4. Compile test against the bstrlib and bstrwrap modules.
5. Run test and ensure that 0 errors are reported.
6. Compile each of the examples (except for the "re" example, which may be
complicated and is not a real test of bstrlib and except for the mfcbench
example which is Windows specific.)
7. Run each of the examples.
The builds must have 0 errors, and should have the absolute minimum number of
warnings (in most cases can be reduced to 0.) The result of execution should
be essentially identical on each platform.
Performance
-----------
Different CPU and compilers have different capabilities in terms of
performance. It is possible for Bstrlib to assume performance
characteristics that a platform doesn't have (since it was primarily
developed on just one platform). The goal of Bstrlib is to provide very good
performance on all platforms regardless of this but without resorting to
extreme measures (such as using assembly language, or non-portable intrinsics
or library extensions.)
There are two performance benchmarks that can be found in the example/
directory. They are: cbench.c and cppbench.cpp. These are variations and
expansions of a benchmark for another string library. They don't cover all
string functionality, but do include the most basic functions which will be
common in most string manipulation kernels.
...............................................................................
Feedback
--------
In all cases, you may email issues found to the primary author of Bstrlib at
the email address: websnarf@users.sourceforge.net
===============================================================================

View File

@ -1,217 +0,0 @@
Better String library Security Statement
----------------------------------------
by Paul Hsieh
===============================================================================
Introduction
------------
The Better String library (hereafter referred to as Bstrlib) is an attempt to
provide improved string processing functionality to the C and C++ languages.
At the heart of the Bstrlib is the management of "bstring"s which are a
significant improvement over '\0' terminated char buffers. See the
accompanying documenation file bstrlib.txt for more information.
DISCLAIMER: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Like any software, there is always a possibility of failure due to a flawed
implementation. Nevertheless a good faith effort has been made to minimize
such flaws in Bstrlib. Use of Bstrlib by itself will not make an application
secure or free from implementation failures, however, it is the author's
conviction that use of Bstrlib can greatly facilitate the creation of
software meeting the highest possible standards of security.
Part of the reason why this document has been created, is for the purpose of
security auditing, or the creation of further "Statements on Security" for
software that is created that uses Bstrlib. An auditor may check the claims
below against Bstrlib, and use this as a basis for analysis of software which
uses Bstrlib.
===============================================================================
Statement on Security
---------------------
This is a document intended to give consumers of the Better String Library
who are interested in security an idea of where the Better String Library
stands on various security issues. Any deviation observed in the actual
library itself from the descriptions below should be considered an
implementation error, not a design flaw.
This statement is not an analytical proof of correctness or an outline of one
but rather an assertion similar to a scientific claim or hypothesis. By use,
testing and open independent examination (otherwise known as scientific
falsifiability), the credibility of the claims made below can rise to the
level of an established theory.
Common security issues:
.......................
1. Buffer Overflows
The Bstrlib API allows the programmer a way to deal with strings without
having to deal with the buffers containing them. Ordinary usage of the
Bstrlib API itself makes buffer overflows impossible.
Furthermore, the Bstrlib API has a superset of basic string functionality as
compared to the C library's char * functions, C++'s std::string class and
Microsoft's MFC based CString class. It also has abstracted mechanisms for
dealing with IO. This is important as it gives developers a way of migrating
all their code from a functionality point of view.
2. Memory size overflow/wrap around attack
By design, Bstrlib is impervious to memory size overflow attacks. The
reason is that it detects length overflows and leads to a result error before
the operation attempts to proceed. Attempted conversions of char* strings
which may have lengths greater than INT_MAX are detected and the conversion
is aborted. If the memory to hold the string exceeds the available memory
for it, again, the result is aborted without changing the prior state of the
strings.
3. Constant string protection
Bstrlib implements runtime enforced constant and read-only string semantics.
I.e., bstrings which are declared as constant via the bsStatic() macro cannot
be modified or deallocated directly through the Bstrlib API, and this cannot
be subverted by casting or other type coercion. This is independent of the
use of the const_bstring data type.
The Bstrlib C API uses the type const_bstring to specify bstring parameters
whose contents do not change. Although the C language cannot enforce this,
this is nevertheless guaranteed by the implementation of the Bstrlib library
of C functions. The C++ API enforces the const attribute on CBString types
correctly.
4. Aliased bstring support
Bstrlib detects and supports aliased parameter management throughout the API.
The kind of aliasing that is allowed is the one where pointers of the same
basic type may be pointing to overlapping objects (this is the assumption the
ANSI C99 specification makes.) Each function behaves as if all read-only
parameters were copied to temporaries which are used in their stead before
the function is enacted (it rarely actually does this). No function in the
Bstrlib uses the "restrict" parameter attribute from the ANSI C99
specification.
5. Information leaking
In bstraux.h, using the semantically equivalent macros bSecureDestroy() and
bSecureWriteProtect() in place of bdestroy() and bwriteprotect() respectively
will ensure that stale data does not linger in the heap's free space after
strings have been released back to memory. Created bstrings or CBStrings
are not linked to anything external to themselves, and thus cannot expose
deterministic data leaking. If a bstring is resized, the preimage may exist
as a copy that is released to the heap. Thus for sensitive data, the bstring
should be sufficiently presized before manipulated so that it is not resized.
bSecureInput() has been supplied in bstraux.c, which can be used to obtain
input securely without any risk of leaving any part of the input image in the
heap except for the allocated bstring that is returned.
6. Memory leaking
Bstrlib can be built using memdbg.h enabled via the BSTRLIB_MEMORY_DEBUG
macro. User generated definitions for malloc, realloc and free can then be
supplied which can implement special strategies for memory corruption
detection or memory leaking. Otherwise, bstrlib does not do anything out of
the ordinary to attempt to deal with the standard problem of memory leaking
(i.e., losing references to allocated memory) when programming in the C and
C++ languages. However, it does not compound the problem any more than exists
either, as it doesn't have any intrinsic inescapable leaks in it. Bstrlib
does not preclude the use of automatic garbage collection mechanisms such as
the Boehm garbage collector.
7. Encryption
Bstrlib does not present any built-in encryption mechanism. However, it
supports full binary contents in its data buffers, so any standard block
based encryption mechanism can make direct use of bstrings/CBStrings for
buffer management.
8. Double freeing
Freeing a pointer that is already free is an extremely rare, but nevertheless
a potentially ruthlessly corrupting operation (its possible to cause Win 98 to
reboot, by calling free mulitiple times on already freed data using the WATCOM
CRT.) Bstrlib invalidates the bstring header data before freeing, so that in
many cases a double free will be detected and an error will be reported
(though this behaviour is not guaranteed and should not be relied on).
Using bstrFree pervasively (instead of bdestroy) can lead to somewhat
improved invalid free avoidance (it is completely safe whenever bstring
instances are only stored in unique variables). For example:
struct tagbstring hw = bsStatic ("Hello, world");
bstring cpHw = bstrcpy (&hw);
#ifdef NOT_QUITE_AS_SAFE
bdestroy (cpHw); /* Never fail */
bdestroy (cpHw); /* Error sometimes detected at runtime */
bdestroy (&hw); /* Error detected at run time */
#else
bstrFree (cpHw); /* Never fail */
bstrFree (cpHw); /* Will do nothing */
bstrFree (&hw); /* Will lead to a compile time error */
#endif
9. Resource based denial of service
bSecureInput() has been supplied in bstraux.c. It has an optional upper limit
for input length. But unlike fgets(), it is also easily determined if the
buffer has been truncated early. In this way, a program can set an upper
limit on input sizes while still allowing for implementing context specific
truncation semantics (i.e., does the program consume but dump the extra
input, or does it consume it in later inputs?)
10. Mixing char *'s and bstrings
The bstring and char * representations are not identical. So there is a risk
when converting back and forth that data may lost. Essentially bstrings can
contain '\0' as a valid non-terminating character, while char * strings
cannot and in fact must use the character as a terminator. The risk of data
loss is very low, since:
A) the simple method of only using bstrings in a char * semantically
compatible way is both easy to achieve and pervasively supported.
B) obtaining '\0' content in a string is either deliberate or indicative
of another, likely more serious problem in the code.
C) the library comes with various functions which deal with this issue
(namely: bfromcstr(), bstr2cstr (), and bSetCstrChar ())
Marginal security issues:
.........................
11. 8-bit versus 9-bit portability
Bstrlib uses CHAR_BIT and other limits.h constants to the maximum extent
possible to avoid portability problems. However, Bstrlib has not been tested
on any system that does not represent char as 8-bits. So whether or not it
works on 9-bit systems is an open question. It is recommended that Bstrlib be
carefully auditted by anyone using a system in which CHAR_BIT is not 8.
12. EBCDIC/ASCII/UTF-8 data representation attacks.
Bstrlib uses ctype.h functions to ensure that it remains portable to non-
ASCII systems. It also checks range to make sure it is well defined even for
data that ANSI does not define for the ctype functions.
Obscure issues:
...............
13. Data attributes
There is no support for a Perl-like "taint" attribute, although this is a
fairly straightforward exercise using C++'s type system.

File diff suppressed because it is too large Load Diff

View File

@ -1,423 +0,0 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2015, and is covered by the BSD open source
* license. Refer to the accompanying documentation for details on usage and
* license.
*/
/*
* testaux.c
*
* This file is the C unit test for the bstraux module of Bstrlib.
*/
#include <stdio.h>
#include "bstrlib.h"
#include "bstraux.h"
static int tWrite (const void * buf, size_t elsize, size_t nelem, void * parm) {
bstring b = (bstring) parm;
size_t i;
if (NULL == b || NULL == buf || 0 == elsize || 0 == nelem)
return -__LINE__;
for (i=0; i < nelem; i++) {
if (0 > bcatblk (b, buf, elsize)) break;
buf = (const void *) (elsize + (const char *) buf);
}
return (int) i;
}
int test0 (void) {
struct bwriteStream * ws;
bstring s;
int ret = 0;
printf ("TEST: struct bwriteStream functions.\n");
ws = bwsOpen ((bNwrite) tWrite, (s = bfromcstr ("")));
bwsBuffLength (ws, 8);
ret += 8 != bwsBuffLength (ws, 0);
bwsWriteBlk (ws, bsStaticBlkParms ("Hello "));
ret += 0 == biseqcstr (s, "");
bwsWriteBlk (ws, bsStaticBlkParms ("World\n"));
ret += 0 == biseqcstr (s, "Hello Wo");
ret += s != bwsClose (ws);
ret += 0 == biseqcstr (s, "Hello World\n");
printf ("\t# failures: %d\n", ret);
return ret;
}
int test1 (void) {
struct tagbstring t = bsStatic ("Hello world");
bstring b, c, d;
int ret = 0;
printf ("TEST: bTail and bHead functions.\n");
b = bTail (&t, 5);
c = bHead (&t, 5);
ret += 0 >= biseqcstr (b, "world");
ret += 0 >= biseqcstr (c, "Hello");
bdestroy (b);
bdestroy (c);
b = bTail (&t, 0);
c = bHead (&t, 0);
ret += 0 >= biseqcstr (b, "");
ret += 0 >= biseqcstr (c, "");
bdestroy (b);
bdestroy (c);
d = bstrcpy (&t);
b = bTail (d, 5);
c = bHead (d, 5);
ret += 0 >= biseqcstr (b, "world");
ret += 0 >= biseqcstr (c, "Hello");
bdestroy (b);
bdestroy (c);
bdestroy (d);
printf ("\t# failures: %d\n", ret);
return ret;
}
int test2 (void) {
struct tagbstring t = bsStatic ("Hello world");
bstring b;
int ret = 0, reto;
printf ("TEST: bSetChar function.\n");
ret += 0 <= bSetChar (&t, 4, ',');
ret += 0 > bSetChar (b = bstrcpy (&t), 4, ',');
ret += 0 >= biseqcstr (b, "Hell, world");
ret += 0 <= bSetChar (b, -1, 'x');
b->slen = 2;
ret += 0 > bSetChar (b, 1, 'i');
ret += 0 >= biseqcstr (b, "Hi");
ret += 0 > bSetChar (b, 2, 's');
ret += 0 >= biseqcstr (b, "His");
ret += 0 > bSetChar (b, 1, '\0');
ret += blength (b) != 3;
ret += bchare (b, 0, '?') != 'H';
ret += bchare (b, 1, '?') != '\0';
ret += bchare (b, 2, '?') != 's';
bdestroy (b);
printf ("\t# failures: %d\n", ret);
reto = ret;
ret = 0;
printf ("TEST: bSetCstrChar function.\n");
ret += 0 <= bSetCstrChar (&t, 4, ',');
ret += 0 > bSetCstrChar (b = bstrcpy (&t), 4, ',');
ret += 0 >= biseqcstr (b, "Hell, world");
ret += 0 <= bSetCstrChar (b, -1, 'x');
b->slen = 2;
ret += 0 > bSetCstrChar (b, 1, 'i');
ret += 0 >= biseqcstr (b, "Hi");
ret += 0 > bSetCstrChar (b, 2, 's');
ret += 0 >= biseqcstr (b, "His");
ret += 0 > bSetCstrChar (b, 1, '\0');
ret += blength (b) != 1;
ret += bchare (b, 0, '?') != 'H';
bdestroy (b);
printf ("\t# failures: %d\n", ret);
return reto + ret;
}
int test3 (void) {
struct tagbstring t = bsStatic ("Hello world");
bstring b;
int ret = 0;
printf ("TEST: bFill function.\n");
ret += 0 <= bFill (&t, 'x', 7);
ret += 0 > bFill (b = bstrcpy (&t), 'x', 7);
ret += 0 >= biseqcstr (b, "xxxxxxx");
ret += 0 <= bFill (b, 'x', -1);
ret += 0 > bFill (b, 'x', 0);
ret += 0 >= biseqcstr (b, "");
bdestroy (b);
printf ("\t# failures: %d\n", ret);
return ret;
}
int test4 (void) {
struct tagbstring t = bsStatic ("foo");
bstring b;
int ret = 0;
printf ("TEST: bReplicate function.\n");
ret += 0 <= bReplicate (&t, 4);
ret += 0 <= bReplicate (b = bstrcpy (&t), -1);
ret += 0 > bReplicate (b, 4);
ret += 0 >= biseqcstr (b, "foofoofoofoo");
ret += 0 > bReplicate (b, 0);
ret += 0 >= biseqcstr (b, "");
bdestroy (b);
printf ("\t# failures: %d\n", ret);
return ret;
}
int test5 (void) {
struct tagbstring t = bsStatic ("Hello world");
bstring b;
int ret = 0;
printf ("TEST: bReverse function.\n");
ret += 0 <= bReverse (&t);
ret += 0 > bReverse (b = bstrcpy (&t));
ret += 0 >= biseqcstr (b, "dlrow olleH");
b->slen = 0;
ret += 0 > bReverse (b);
ret += 0 >= biseqcstr (b, "");
bdestroy (b);
printf ("\t# failures: %d\n", ret);
return ret;
}
int test6 (void) {
struct tagbstring t = bsStatic ("Hello world");
bstring b;
int ret = 0;
printf ("TEST: bInsertChrs function.\n");
ret += 0 <= bInsertChrs (&t, 6, 4, 'x', '?');
ret += 0 > bInsertChrs (b = bstrcpy (&t), 6, 4, 'x', '?');
ret += 0 >= biseqcstr (b, "Hello xxxxworld");
bdestroy (b);
printf ("\t# failures: %d\n", ret);
return ret;
}
int test7 (void) {
struct tagbstring t = bsStatic (" i am ");
bstring b;
int ret = 0;
printf ("TEST: bJustify functions.\n");
ret += 0 <= bJustifyLeft (&t, ' ');
ret += 0 <= bJustifyRight (&t, 8, ' ');
ret += 0 <= bJustifyMargin (&t, 8, ' ');
ret += 0 <= bJustifyCenter (&t, 8, ' ');
ret += 0 > bJustifyLeft (b = bstrcpy (&t), ' ');
ret += 0 >= biseqcstr (b, "i am");
ret += 0 > bJustifyRight (b, 8, ' ');
ret += 0 >= biseqcstr (b, " i am");
ret += 0 > bJustifyMargin (b, 8, ' ');
ret += 0 >= biseqcstr (b, "i am");
ret += 0 > bJustifyCenter (b, 8, ' ');
ret += 0 >= biseqcstr (b, " i am");
bdestroy (b);
printf ("\t# failures: %d\n", ret);
return ret;
}
int test8 (void) {
struct tagbstring t = bsStatic ("Hello world");
bstring b;
char * c;
int ret = 0;
printf ("TEST: NetStr functions.\n");
c = bStr2NetStr (&t);
ret += 0 != strcmp (c, "11:Hello world,");
b = bNetStr2Bstr (c);
ret += 0 >= biseq (b, &t);
bdestroy (b);
bcstrfree (c);
printf ("\t# failures: %d\n", ret);
return ret;
}
int test9 (void) {
struct tagbstring t = bsStatic ("Hello world");
bstring b, c;
int err, ret = 0;
printf ("TEST: Base 64 codec.\n");
b = bBase64Encode (&t);
ret += 0 >= biseqcstr (b, "SGVsbG8gd29ybGQ=");
c = bBase64DecodeEx (b, &err);
ret += 0 != err;
ret += 0 >= biseq (c, &t);
bdestroy (b);
bdestroy (c);
printf ("\t# failures: %d\n", ret);
return ret;
}
int test10 (void) {
struct tagbstring t = bsStatic ("Hello world");
bstring b, c;
int err, ret = 0;
printf ("TEST: UU codec.\n");
b = bUuEncode (&t);
ret += 0 >= biseqcstr (b, "+2&5L;&\\@=V]R;&0`\r\n");
c = bUuDecodeEx (b, &err);
ret += 0 != err;
ret += 0 >= biseq (c, &t);
bdestroy (b);
bdestroy (c);
printf ("\t# failures: %d\n", ret);
return ret;
}
int test11 (void) {
struct tagbstring t = bsStatic ("Hello world");
unsigned char Ytstr[] = {0x72, 0x8f, 0x96, 0x96, 0x99, 0x4a, 0xa1, 0x99, 0x9c, 0x96, 0x8e};
bstring b, c;
int ret = 0;
printf ("TEST: Y codec.\n");
b = bYEncode (&t);
ret += 11 != b->slen;
ret += 0 >= bisstemeqblk (b, Ytstr, 11);
c = bYDecode (b);
ret += 0 >= biseq (c, &t);
bdestroy (b);
bdestroy (c);
printf ("\t# failures: %d\n", ret);
return ret;
}
int test12 (void) {
struct tagbstring t = bsStatic ("Hello world");
struct bStream * s;
bstring b;
int ret = 0;
printf ("TEST: bsFromBstr.\n");
ret = bsread (b = bfromcstr (""), s = bsFromBstr (&t), 6);
ret += 1 != biseqcstr (b, "Hello ");
if (b) b->slen = 0;
ret = bsread (b, s, 6);
ret += 1 != biseqcstr (b, "world");
bdestroy (b);
bsclose (s);
printf ("\t# failures: %d\n", ret);
return ret;
}
struct vfgetc {
int ofs;
bstring base;
};
static int test13_fgetc (void * ctx) {
struct vfgetc * vctx = (struct vfgetc *) ctx;
int c;
if (NULL == vctx || NULL == vctx->base) return EOF;
if (vctx->ofs >= blength (vctx->base)) return EOF;
c = bchare (vctx->base, vctx->ofs, EOF);
vctx->ofs++;
return c;
}
int test13 (void) {
struct tagbstring t0 = bsStatic ("Random String, long enough to cause to reallocing");
struct vfgetc vctx;
bstring b;
int ret = 0;
int i;
printf ("TEST: bSecureInput, bSecureDestroy.\n");
for (i=0; i < 1000; i++) {
unsigned char * h;
vctx.ofs = 0;
vctx.base = &t0;
b = bSecureInput (INT_MAX, '\n', (bNgetc) test13_fgetc, &vctx);
ret += 1 != biseq (b, &t0);
h = b->data;
bSecureDestroy (b);
/* WARNING! Technically undefined code follows (h has been freed): */
ret += (0 == memcmp (h, t0.data, t0.slen));
if (ret) break;
}
printf ("\t# failures: %d\n", ret);
return ret;
}
int test14_aux(bstring b, const char* chkVal) {
int ret = 0;
ret += 0 != bSGMLEncode (b);
ret += 1 != biseqcstr (b, chkVal);
return ret;
}
int test14 (void) {
bstring b;
int ret = 0;
printf ("TEST: bSGMLEncode.\n");
ret += test14_aux (b = bfromStatic ("<\"Hello, you, me, & world\">"), "&lt;&quot;Hello, you, me, &amp; world&quot;&gt;");
printf ("\t# failures: %d\n", ret);
return ret;
}
int main () {
int ret = 0;
printf ("Direct case testing of bstraux functions\n");
ret += test0 ();
ret += test1 ();
ret += test2 ();
ret += test3 ();
ret += test4 ();
ret += test5 ();
ret += test6 ();
ret += test7 ();
ret += test8 ();
ret += test9 ();
ret += test10 ();
ret += test11 ();
ret += test12 ();
ret += test13 ();
ret += test14 ();
printf ("# test failures: %d\n", ret);
return 0;
}

View File

@ -1,249 +0,0 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2015, and is covered by the BSD open source
* license and the GPL. Refer to the accompanying documentation for details
* on usage and license.
*/
/*
* utf8util.c
*
* This file is not necessarily part of the core bstring library itself, but
* is just an generic module for implementing utf8 utility functions.
*/
#include "utf8util.h"
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
/* Surrogate range is wrong, there is a maximum, the BOM alias is illegal and 0xFFFF is illegal */
#define isLegalUnicodeCodePoint(v) ((((v) < 0xD800L) || ((v) > 0xDFFFL)) && (((unsigned long)(v)) <= 0x0010FFFFL) && (((v)|0x1F0001) != 0x1FFFFFL))
void utf8IteratorInit (struct utf8Iterator* iter, unsigned char* data, int slen) {
if (iter) {
iter->data = data;
iter->slen = (iter->data && slen >= 0) ? slen : -1;
iter->start = -1;
iter->next = (iter->slen >= 0) ? 0 : -1;
iter->error = (iter->slen >= 0) ? 0 : 1;
}
}
void utf8IteratorUninit (struct utf8Iterator* iter) {
if (iter) {
iter->data = NULL;
iter->slen = -1;
iter->start = iter->next = -1;
}
}
int utf8ScanBackwardsForCodePoint (unsigned char* msg, int len, int pos, cpUcs4* out) {
cpUcs4 v1, v2, v3, v4, x;
int ret;
if (NULL == msg || len < 0 || (unsigned) pos >= (unsigned) len) {
return -__LINE__;
}
if (!out) out = &x;
ret = 0;
if (msg[pos] < 0x80) {
*out = msg[pos];
return 0;
} else if (msg[pos] < 0xC0) {
if (0 == pos) return -__LINE__;
ret = -__LINE__;
if (msg[pos-1] >= 0xC1 && msg[pos-1] < 0xF8) {
pos--;
ret = 1;
} else {
if (1 == pos) return -__LINE__;
if ((msg[pos-1] | 0x3F) != 0xBF) return -__LINE__;
if (msg[pos-2] >= 0xE0 && msg[pos-2] < 0xF8) {
pos -= 2;
ret = 2;
} else {
if (2 == pos) return -__LINE__;
if ((msg[pos-2] | 0x3F) != 0xBF) return -__LINE__;
if ((msg[pos-3]|0x07) == 0xF7) {
pos -= 3;
ret = 3;
} else return -__LINE__;
}
}
}
if (msg[pos] < 0xE0) {
if (pos + 1 >= len) return -__LINE__;
v1 = msg[pos] & ~0xE0;
v2 = msg[pos+1] & ~0xC0;
v1 = (v1 << 6) + v2;
if (v1 < 0x80) return -__LINE__;
*out = v1;
return ret;
}
if (msg[pos] < 0xF0) {
if (pos + 2 >= len) return -__LINE__;
v1 = msg[pos] & ~0xF0;
v2 = msg[pos+1] & ~0xC0;
v3 = msg[pos+2] & ~0xC0;
v1 = (v1 << 12) + (v2 << 6) + v3;
if (v1 < 0x800) return -__LINE__;
if (!isLegalUnicodeCodePoint(v1)) return -__LINE__;
*out = v1;
return ret;
}
if (msg[pos] >= 0xF8) return -__LINE__;
if (pos + 3 >= len) return -__LINE__;
v1 = msg[pos] & ~0xF8;
v2 = msg[pos+1] & ~0xC0;
v3 = msg[pos+2] & ~0xC0;
v4 = msg[pos+3] & ~0xC0;
v1 = (v1 << 18) + (v2 << 12) + (v3 << 6) + v4;
if (v1 < 0x10000) return -__LINE__;
if (!isLegalUnicodeCodePoint(v1)) return -__LINE__;
*out = v1;
return ret;
}
/*
Code point UTF-8
---------- -----
U-00000000 - U-0000007F: 0xxxxxxx
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
*/
/*
* Returns next read code point for iterator.
*
* iter->data + iter->start points at the characters just read.
*
* iter->data + iter->next points at the characters that will be read next.
*
* iter->error is boolean indicating whether or not last read contained an error.
*/
cpUcs4 utf8IteratorGetNextCodePoint (struct utf8Iterator* iter, cpUcs4 errCh) {
unsigned char * chrs;
unsigned char c, d, e;
long v;
int i, ofs;
if (NULL == iter || iter->next < 0) return errCh;
if (iter->next >= iter->slen) {
iter->start = iter->slen;
return errCh;
}
if (NULL == iter->data || iter->next < 0 || utf8IteratorNoMore(iter)) return errCh;
chrs = iter->data + iter->next;
iter->error = 0;
c = chrs[0];
ofs = 0;
if (c < 0xC0 || c > 0xFD) {
if (c >= 0x80) goto ErrMode;
v = c;
ofs = 1;
} else if (c < 0xE0) {
if (iter->next >= iter->slen + 1) goto ErrMode;
v = (c << 6u) - (0x0C0 << 6u);
c = (unsigned char) ((unsigned) chrs[1] - 0x080);
v += c;
if (c >= 0x40 || v < 0x80) goto ErrMode;
ofs = 2;
} else if (c < 0xF0) {
if (iter->next >= iter->slen + 2) goto ErrMode;
v = (c << 12) - (0x0E0 << 12u);
c = (unsigned char) ((unsigned) chrs[1] - 0x080);
d = (unsigned char) ((unsigned) chrs[2] - 0x080);
v += (c << 6u) + d;
if ((c|d) >= 0x40 || v < 0x800 || !isLegalUnicodeCodePoint (v)) goto ErrMode;
ofs = 3;
} else if (c < 0xF8) {
if (iter->next >= iter->slen + 3) goto ErrMode;
v = (c << 18) - (0x0F0 << 18u);
c = (unsigned char) ((unsigned) chrs[1] - 0x080);
d = (unsigned char) ((unsigned) chrs[2] - 0x080);
e = (unsigned char) ((unsigned) chrs[3] - 0x080);
v += (c << 12u) + (d << 6u) + e;
if ((c|d|e) >= 0x40 || v < 0x10000 || !isLegalUnicodeCodePoint (v)) goto ErrMode;
ofs = 4;
} else { /* 5 and 6 byte encodings are invalid */
ErrMode:;
iter->error = 1;
v = errCh;
for (i = iter->next+1; i < iter->slen; i++) if ((iter->data[i] & 0xC0) != 0x80) break;
ofs = i - iter->next;
}
iter->start = iter->next;
iter->next += ofs;
return v;
}
/*
* Returns next read code point for iterator.
*
* iter->data + iter->start points at the characters to be read.
*
* iter->data + iter->next points at the characters that will be read next.
*
* iter->error is boolean indicating whether or not last read contained an error.
*/
cpUcs4 utf8IteratorGetCurrCodePoint (struct utf8Iterator* iter, cpUcs4 errCh) {
unsigned char * chrs;
unsigned char c, d, e;
long v;
if (NULL == iter || iter->next < 0) return errCh;
if (iter->next >= iter->slen) {
iter->start = iter->slen;
return errCh;
}
if (NULL == iter->data || iter->next < 0 || utf8IteratorNoMore(iter)) return errCh;
chrs = iter->data + iter->next;
iter->error = 0;
c = chrs[0];
if (c < 0xC0 || c > 0xFD) {
if (c >= 0x80) goto ErrMode;
v = c;
} else if (c < 0xE0) {
if (iter->next >= iter->slen + 1) goto ErrMode;
v = (c << 6u) - (0x0C0 << 6u);
c = (unsigned char) ((unsigned) chrs[1] - 0x080);
v += c;
if (c >= 0x40 || v < 0x80) goto ErrMode;
} else if (c < 0xF0) {
if (iter->next >= iter->slen + 2) goto ErrMode;
v = (c << 12lu) - (0x0E0 << 12u);
c = (unsigned char) ((unsigned) chrs[1] - 0x080);
d = (unsigned char) ((unsigned) chrs[2] - 0x080);
v += (c << 6u) + d;
if ((c|d) >= 0x40 || v < 0x800 || !isLegalUnicodeCodePoint (v)) goto ErrMode;
} else if (c < 0xF8) {
if (iter->next >= iter->slen + 3) goto ErrMode;
v = (c << 18lu) - (0x0F0 << 18u);
c = (unsigned char) ((unsigned) chrs[1] - 0x080);
d = (unsigned char) ((unsigned) chrs[2] - 0x080);
e = (unsigned char) ((unsigned) chrs[3] - 0x080);
v += (c << 12lu) + (d << 6u) + e;
if ((c|d|e) >= 0x40 || v < 0x10000 || !isLegalUnicodeCodePoint (v)) goto ErrMode;
} else { /* 5 and 6 byte encodings are invalid */
ErrMode:;
iter->error = 1;
v = errCh;
}
return v;
}

View File

@ -1,62 +0,0 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2015, and is covered by the BSD open source
* license and the GPL. Refer to the accompanying documentation for details
* on usage and license.
*/
/*
* utf8util.h
*
* This file defines the interface to the utf8 utility functions.
*/
#ifndef UTF8_UNICODE_UTILITIES
#define UTF8_UNICODE_UTILITIES
#include <limits.h>
#ifdef __cplusplus
extern "C" {
#endif
#if INT_MAX >= 0x7fffffffUL
typedef int cpUcs4;
#elif LONG_MAX >= 0x7fffffffUL
typedef long cpUcs4;
#else
#error This compiler is not supported
#endif
#if UINT_MAX == 0xFFFF
typedef unsigned int cpUcs2;
#elif USHRT_MAX == 0xFFFF
typedef unsigned short cpUcs2;
#elif UCHAR_MAX == 0xFFFF
typedef unsigned char cpUcs2;
#else
#error This compiler is not supported
#endif
#define isLegalUnicodeCodePoint(v) ((((v) < 0xD800L) || ((v) > 0xDFFFL)) && (((unsigned long)(v)) <= 0x0010FFFFL) && (((v)|0x1F0001) != 0x1FFFFFL))
struct utf8Iterator {
unsigned char* data;
int slen;
int start, next;
int error;
};
#define utf8IteratorNoMore(it) (!(it) || (it)->next >= (it)->slen)
extern void utf8IteratorInit (struct utf8Iterator* iter, unsigned char* data, int slen);
extern void utf8IteratorUninit (struct utf8Iterator* iter);
extern cpUcs4 utf8IteratorGetNextCodePoint (struct utf8Iterator* iter, cpUcs4 errCh);
extern cpUcs4 utf8IteratorGetCurrCodePoint (struct utf8Iterator* iter, cpUcs4 errCh);
extern int utf8ScanBackwardsForCodePoint (unsigned char* msg, int len, int pos, cpUcs4* out);
#ifdef __cplusplus
}
#endif
#endif /* UTF8_UNICODE_UTILITIES */

View File

@ -1,323 +0,0 @@
#include "chunks.h"
#include <limits.h>
#define NORMAL 0
#define HIGHLIGHTED 1
#define BUFFER_SIZE 0x10000
#define CHUNK_SIZE 0x1000
#define READ_CHUNK_MASK Q_INT64_C(0xfffffffffffff000)
// ***************************************** Constructors and file settings
Chunks::Chunks()
{
QBuffer *buf = new QBuffer();
setIODevice(*buf);
}
Chunks::Chunks(QIODevice &ioDevice)
{
setIODevice(ioDevice);
}
bool Chunks::setIODevice(QIODevice &ioDevice)
{
_ioDevice = &ioDevice;
bool ok = _ioDevice->open(QIODevice::ReadOnly);
if (ok) // Try to open IODevice
{
_size = _ioDevice->size();
_ioDevice->close();
}
else // Fallback is an empty buffer
{
QBuffer *buf = new QBuffer();
_ioDevice = buf;
_size = 0;
}
_chunks.clear();
_pos = 0;
return ok;
}
// ***************************************** Getting data out of Chunks
QByteArray Chunks::data(qint64 pos, qint64 maxSize, QByteArray *highlighted)
{
qint64 ioDelta = 0;
int chunkIdx = 0;
Chunk chunk;
QByteArray buffer;
// Do some checks and some arrangements
if (highlighted)
highlighted->clear();
if (pos >= _size)
return buffer;
if (maxSize < 0)
maxSize = _size;
else
if ((pos + maxSize) > _size)
maxSize = _size - pos;
_ioDevice->open(QIODevice::ReadOnly);
while (maxSize > 0)
{
chunk.absPos = LLONG_MAX;
bool chunksLoopOngoing = true;
while ((chunkIdx < _chunks.count()) && chunksLoopOngoing)
{
// In this section, we track changes before our required data and
// we take the editdet data, if availible. ioDelta is a difference
// counter to justify the read pointer to the original data, if
// data in between was deleted or inserted.
chunk = _chunks[chunkIdx];
if (chunk.absPos > pos)
chunksLoopOngoing = false;
else
{
chunkIdx += 1;
qint64 count;
qint64 chunkOfs = pos - chunk.absPos;
if (maxSize > ((qint64)chunk.data.size() - chunkOfs))
{
count = (qint64)chunk.data.size() - chunkOfs;
ioDelta += CHUNK_SIZE - chunk.data.size();
}
else
count = maxSize;
if (count > 0)
{
buffer += chunk.data.mid(chunkOfs, (int)count);
maxSize -= count;
pos += count;
if (highlighted)
*highlighted += chunk.dataChanged.mid(chunkOfs, (int)count);
}
}
}
if ((maxSize > 0) && (pos < chunk.absPos))
{
// In this section, we read data from the original source. This only will
// happen, whe no copied data is available
qint64 byteCount;
QByteArray readBuffer;
if ((chunk.absPos - pos) > maxSize)
byteCount = maxSize;
else
byteCount = chunk.absPos - pos;
maxSize -= byteCount;
_ioDevice->seek(pos + ioDelta);
readBuffer = _ioDevice->read(byteCount);
buffer += readBuffer;
if (highlighted)
*highlighted += QByteArray(readBuffer.size(), NORMAL);
pos += readBuffer.size();
}
}
_ioDevice->close();
return buffer;
}
bool Chunks::write(QIODevice &iODevice, qint64 pos, qint64 count)
{
if (count == -1)
count = _size;
bool ok = iODevice.open(QIODevice::WriteOnly);
if (ok)
{
for (qint64 idx=pos; idx < count; idx += BUFFER_SIZE)
{
QByteArray ba = data(idx, BUFFER_SIZE);
iODevice.write(ba);
}
iODevice.close();
}
return ok;
}
// ***************************************** Set and get highlighting infos
void Chunks::setDataChanged(qint64 pos, bool dataChanged)
{
if ((pos < 0) || (pos >= _size))
return;
int chunkIdx = getChunkIndex(pos);
qint64 posInBa = pos - _chunks[chunkIdx].absPos;
_chunks[chunkIdx].dataChanged[(int)posInBa] = char(dataChanged);
}
bool Chunks::dataChanged(qint64 pos)
{
QByteArray highlighted;
data(pos, 1, &highlighted);
return bool(highlighted.at(0));
}
// ***************************************** Search API
qint64 Chunks::indexOf(const QByteArray &ba, qint64 from)
{
qint64 result = -1;
QByteArray buffer;
for (qint64 pos=from; (pos < _size) && (result < 0); pos += BUFFER_SIZE)
{
buffer = data(pos, BUFFER_SIZE + ba.size() - 1);
int findPos = buffer.indexOf(ba);
if (findPos >= 0)
result = pos + (qint64)findPos;
}
return result;
}
qint64 Chunks::lastIndexOf(const QByteArray &ba, qint64 from)
{
qint64 result = -1;
QByteArray buffer;
for (qint64 pos=from; (pos > 0) && (result < 0); pos -= BUFFER_SIZE)
{
qint64 sPos = pos - BUFFER_SIZE - (qint64)ba.size() + 1;
if (sPos < 0)
sPos = 0;
buffer = data(sPos, pos - sPos);
int findPos = buffer.lastIndexOf(ba);
if (findPos >= 0)
result = sPos + (qint64)findPos;
}
return result;
}
// ***************************************** Char manipulations
bool Chunks::insert(qint64 pos, char b)
{
if ((pos < 0) || (pos > _size))
return false;
int chunkIdx;
if (pos == _size)
chunkIdx = getChunkIndex(pos-1);
else
chunkIdx = getChunkIndex(pos);
qint64 posInBa = pos - _chunks[chunkIdx].absPos;
_chunks[chunkIdx].data.insert(posInBa, b);
_chunks[chunkIdx].dataChanged.insert(posInBa, char(1));
for (int idx=chunkIdx+1; idx < _chunks.size(); idx++)
_chunks[idx].absPos += 1;
_size += 1;
_pos = pos;
return true;
}
bool Chunks::overwrite(qint64 pos, char b)
{
if ((pos < 0) || (pos >= _size))
return false;
int chunkIdx = getChunkIndex(pos);
qint64 posInBa = pos - _chunks[chunkIdx].absPos;
_chunks[chunkIdx].data[(int)posInBa] = b;
_chunks[chunkIdx].dataChanged[(int)posInBa] = char(1);
_pos = pos;
return true;
}
bool Chunks::removeAt(qint64 pos)
{
if ((pos < 0) || (pos >= _size))
return false;
int chunkIdx = getChunkIndex(pos);
qint64 posInBa = pos - _chunks[chunkIdx].absPos;
_chunks[chunkIdx].data.remove(posInBa, 1);
_chunks[chunkIdx].dataChanged.remove(posInBa, 1);
for (int idx=chunkIdx+1; idx < _chunks.size(); idx++)
_chunks[idx].absPos -= 1;
_size -= 1;
_pos = pos;
return true;
}
// ***************************************** Utility functions
char Chunks::operator[](qint64 pos)
{
return data(pos, 1)[0];
}
qint64 Chunks::pos()
{
return _pos;
}
qint64 Chunks::size()
{
return _size;
}
int Chunks::getChunkIndex(qint64 absPos)
{
// This routine checks, if there is already a copied chunk available. If os, it
// returns a reference to it. If there is no copied chunk available, original
// data will be copied into a new chunk.
int foundIdx = -1;
int insertIdx = 0;
qint64 ioDelta = 0;
for (int idx=0; idx < _chunks.size(); idx++)
{
Chunk chunk = _chunks[idx];
if ((absPos >= chunk.absPos) && (absPos < (chunk.absPos + chunk.data.size())))
{
foundIdx = idx;
break;
}
if (absPos < chunk.absPos)
{
insertIdx = idx;
break;
}
ioDelta += chunk.data.size() - CHUNK_SIZE;
insertIdx = idx + 1;
}
if (foundIdx == -1)
{
Chunk newChunk;
qint64 readAbsPos = absPos - ioDelta;
qint64 readPos = (readAbsPos & READ_CHUNK_MASK);
_ioDevice->open(QIODevice::ReadOnly);
_ioDevice->seek(readPos);
newChunk.data = _ioDevice->read(CHUNK_SIZE);
_ioDevice->close();
newChunk.absPos = absPos - (readAbsPos - readPos);
newChunk.dataChanged = QByteArray(newChunk.data.size(), char(0));
_chunks.insert(insertIdx, newChunk);
foundIdx = insertIdx;
}
return foundIdx;
}
#ifdef MODUL_TEST
int Chunks::chunkSize()
{
return _chunks.size();
}
#endif

View File

@ -1,76 +0,0 @@
#ifndef CHUNKS_H
#define CHUNKS_H
/** \cond docNever */
/*! The Chunks class is the storage backend for QHexEdit.
*
* When QHexEdit loads data, Chunks access them using a QIODevice interface. When the app uses
* a QByteArray interface, QBuffer is used to provide again a QIODevice like interface. No data
* will be changed, therefore Chunks opens the QIODevice in QIODevice::ReadOnly mode. After every
* access Chunks closes the QIODevice, that's why external applications can overwrite files while
* QHexEdit shows them.
*
* When the the user starts to edit the data, Chunks creates a local copy of a chunk of data (4
* kilobytes) and notes all changes there. Parallel to that chunk, there is a second chunk,
* which keep track of which bytes are changed and which not.
*
*/
#include <QtCore>
struct Chunk
{
QByteArray data;
QByteArray dataChanged;
qint64 absPos;
};
class Chunks
{
public:
// Constructors and file settings
Chunks();
Chunks(QIODevice &ioDevice);
bool setIODevice(QIODevice &ioDevice);
// Getting data out of Chunks
QByteArray data(qint64 pos=0, qint64 count=-1, QByteArray *highlighted=0);
bool write(QIODevice &iODevice, qint64 pos=0, qint64 count=-1);
// Set and get highlighting infos
void setDataChanged(qint64 pos, bool dataChanged);
bool dataChanged(qint64 pos);
// Search API
qint64 indexOf(const QByteArray &ba, qint64 from);
qint64 lastIndexOf(const QByteArray &ba, qint64 from);
// Char manipulations
bool insert(qint64 pos, char b);
bool overwrite(qint64 pos, char b);
bool removeAt(qint64 pos);
// Utility functions
char operator[](qint64 pos);
qint64 pos();
qint64 size();
private:
int getChunkIndex(qint64 absPos);
QIODevice * _ioDevice;
qint64 _pos;
qint64 _size;
QList<Chunk> _chunks;
#ifdef MODUL_TEST
public:
int chunkSize();
#endif
};
/** \endcond docNever */
#endif // CHUNKS_H

View File

@ -1,165 +0,0 @@
#include "commands.h"
#include <QUndoCommand>
// Helper class to store single byte commands
class CharCommand : public QUndoCommand
{
public:
enum CCmd {insert, removeAt, overwrite};
CharCommand(Chunks * chunks, CCmd cmd, qint64 charPos, char newChar,
QUndoCommand *parent=0);
void undo();
void redo();
bool mergeWith(const QUndoCommand *command);
int id() const { return 1234; }
private:
Chunks * _chunks;
qint64 _charPos;
bool _wasChanged;
char _newChar;
char _oldChar;
CCmd _cmd;
};
CharCommand::CharCommand(Chunks * chunks, CCmd cmd, qint64 charPos, char newChar, QUndoCommand *parent)
: QUndoCommand(parent)
{
_chunks = chunks;
_charPos = charPos;
_newChar = newChar;
_cmd = cmd;
}
bool CharCommand::mergeWith(const QUndoCommand *command)
{
const CharCommand *nextCommand = static_cast<const CharCommand *>(command);
bool result = false;
if (_cmd != CharCommand::removeAt)
{
if (nextCommand->_cmd == overwrite)
if (nextCommand->_charPos == _charPos)
{
_newChar = nextCommand->_newChar;
result = true;
}
}
return result;
}
void CharCommand::undo()
{
switch (_cmd)
{
case insert:
_chunks->removeAt(_charPos);
break;
case overwrite:
_chunks->overwrite(_charPos, _oldChar);
_chunks->setDataChanged(_charPos, _wasChanged);
break;
case removeAt:
_chunks->insert(_charPos, _oldChar);
_chunks->setDataChanged(_charPos, _wasChanged);
break;
}
}
void CharCommand::redo()
{
switch (_cmd)
{
case insert:
_chunks->insert(_charPos, _newChar);
break;
case overwrite:
_oldChar = (*_chunks)[_charPos];
_wasChanged = _chunks->dataChanged(_charPos);
_chunks->overwrite(_charPos, _newChar);
break;
case removeAt:
_oldChar = (*_chunks)[_charPos];
_wasChanged = _chunks->dataChanged(_charPos);
_chunks->removeAt(_charPos);
break;
}
}
UndoStack::UndoStack(Chunks * chunks, QObject * parent)
: QUndoStack(parent)
{
_chunks = chunks;
_parent = parent;
}
void UndoStack::insert(qint64 pos, char c)
{
if ((pos >= 0) && (pos <= _chunks->size()))
{
QUndoCommand *cc = new CharCommand(_chunks, CharCommand::insert, pos, c);
this->push(cc);
}
}
void UndoStack::insert(qint64 pos, const QByteArray &ba)
{
if ((pos >= 0) && (pos <= _chunks->size()))
{
QString txt = QString(tr("Inserting %1 bytes")).arg(ba.size());
beginMacro(txt);
for (int idx=0; idx < ba.size(); idx++)
{
QUndoCommand *cc = new CharCommand(_chunks, CharCommand::insert, pos + idx, ba.at(idx));
this->push(cc);
}
endMacro();
}
}
void UndoStack::removeAt(qint64 pos, qint64 len)
{
if ((pos >= 0) && (pos < _chunks->size()))
{
if (len==1)
{
QUndoCommand *cc = new CharCommand(_chunks, CharCommand::removeAt, pos, char(0));
this->push(cc);
}
else
{
QString txt = QString(tr("Delete %1 chars")).arg(len);
beginMacro(txt);
for (qint64 cnt=0; cnt<len; cnt++)
{
QUndoCommand *cc = new CharCommand(_chunks, CharCommand::removeAt, pos, char(0));
push(cc);
}
endMacro();
}
}
}
void UndoStack::overwrite(qint64 pos, char c)
{
if ((pos >= 0) && (pos < _chunks->size()))
{
QUndoCommand *cc = new CharCommand(_chunks, CharCommand::overwrite, pos, c);
this->push(cc);
}
}
void UndoStack::overwrite(qint64 pos, int len, const QByteArray &ba)
{
if ((pos >= 0) && (pos < _chunks->size()))
{
QString txt = QString(tr("Overwrite %1 chars")).arg(len);
beginMacro(txt);
removeAt(pos, len);
insert(pos, ba);
endMacro();
}
}

View File

@ -1,47 +0,0 @@
#ifndef COMMANDS_H
#define COMMANDS_H
/** \cond docNever */
#include <QUndoStack>
#include "chunks.h"
/*! CharCommand is a class to provid undo/redo functionality in QHexEdit.
A QUndoCommand represents a single editing action on a document. CharCommand
is responsable for manipulations on single chars. It can insert. overwrite and
remove characters. A manipulation stores allways two actions
1. redo (or do) action
2. undo action.
CharCommand also supports command compression via mergeWidht(). This allows
the user to execute a undo command contation e.g. 3 steps in a single command.
If you for example insert a new byt "34" this means for the editor doing 3
steps: insert a "00", overwrite it with "03" and the overwrite it with "34". These
3 steps are combined into a single step, insert a "34".
The byte array oriented commands are just put into a set of single byte commands,
which are pooled together with the macroBegin() and macroEnd() functionality of
Qt's QUndoStack.
*/
class UndoStack : public QUndoStack
{
Q_OBJECT
public:
UndoStack(Chunks *chunks, QObject * parent=0);
void insert(qint64 pos, char c);
void insert(qint64 pos, const QByteArray &ba);
void removeAt(qint64 pos, qint64 len=1);
void overwrite(qint64 pos, char c);
void overwrite(qint64 pos, int len, const QByteArray &ba);
private:
Chunks * _chunks;
QObject * _parent;
};
/** \endcond docNever */
#endif // COMMANDS_H

View File

@ -1,502 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

File diff suppressed because it is too large Load Diff

View File

@ -1,394 +0,0 @@
#ifndef QHEXEDIT_H
#define QHEXEDIT_H
#include <QAbstractScrollArea>
#include <QPen>
#include <QBrush>
#include "chunks.h"
#include "commands.h"
/** \mainpage
QHexEdit is a binary editor widget for Qt.
\version Version 0.7.7
\image html qhexedit.png
*/
/** QHexEdit is a hex editor widget written in C++ for the Qt (Qt4, Qt5) framework.
It is a simple editor for binary data, just like QPlainTextEdit is for text
data. There are sip configuration files included, so it is easy to create
bindings for PyQt and you can use this widget also in python 2 and 3.
QHexEdit takes the data of a QByteArray (setData()) and shows it. You can use
the mouse or the keyboard to navigate inside the widget. If you hit the keys
(0..9, a..f) you will change the data. Changed data is highlighted and can be
accessed via data().
Normaly QHexEdit works in the overwrite Mode. You can set overwriteMode(false)
and insert data. In this case the size of data() increases. It is also possible
to delete bytes (del or backspace), here the size of data decreases.
You can select data with keyboard hits or mouse movements. The copy-key will
copy the selected data into the clipboard. The cut-key copies also but delets
it afterwards. In overwrite mode, the paste function overwrites the content of
the (does not change the length) data. In insert mode, clipboard data will be
inserted. The clipboard content is expected in ASCII Hex notation. Unknown
characters will be ignored.
QHexEdit comes with undo/redo functionality. All changes can be undone, by
pressing the undo-key (usually ctr-z). They can also be redone afterwards.
The undo/redo framework is cleared, when setData() sets up a new
content for the editor. You can search data inside the content with indexOf()
and lastIndexOf(). The replace() function is to change located subdata. This
'replaced' data can also be undone by the undo/redo framework.
QHexEdit is based on QIODevice, that's why QHexEdit can handle big amounts of
data. The size of edited data can be more then two gigabytes without any
restrictions.
*/
class QHexEdit : public QAbstractScrollArea
{
Q_OBJECT
/*! Property address area switch the address area on or off. Set addressArea true
(show it), false (hide it).
*/
Q_PROPERTY(bool addressArea READ addressArea WRITE setAddressArea)
/*! Property address area color sets (setAddressAreaColor()) the backgorund
color of address areas. You can also read the color (addressaAreaColor()).
*/
Q_PROPERTY(QColor addressAreaColor READ addressAreaColor WRITE setAddressAreaColor)
/*! Property addressOffset is added to the Numbers of the Address Area.
A offset in the address area (left side) is sometimes usefull, whe you show
only a segment of a complete memory picture. With setAddressOffset() you set
this property - with addressOffset() you get the current value.
*/
Q_PROPERTY(qint64 addressOffset READ addressOffset WRITE setAddressOffset)
/*! Set and get the minimum width of the address area, width in characters.
*/
Q_PROPERTY(int addressWidth READ addressWidth WRITE setAddressWidth)
/*! Switch the ascii area on (true, show it) or off (false, hide it).
*/
Q_PROPERTY(bool asciiArea READ asciiArea WRITE setAsciiArea)
/*! Porperty cursorPosition sets or gets the position of the editor cursor
in QHexEdit. Every byte in data has to cursor positions: the lower and upper
Nibble. Maximum cursor position is factor two of data.size().
*/
Q_PROPERTY(qint64 cursorPosition READ cursorPosition WRITE setCursorPosition)
/*! Property data holds the content of QHexEdit. Call setData() to set the
content of QHexEdit, data() returns the actual content. When calling setData()
with a QByteArray as argument, QHexEdit creates a internal copy of the data
If you want to edit big files please use setData(), based on QIODevice.
*/
Q_PROPERTY(QByteArray data READ data WRITE setData NOTIFY dataChanged)
/*! Switch the highlighting feature on or of: true (show it), false (hide it).
*/
Q_PROPERTY(bool highlighting READ highlighting WRITE setHighlighting)
/*! Property highlighting color sets (setHighlightingColor()) the backgorund
color of highlighted text areas. You can also read the color
(highlightingColor()).
*/
Q_PROPERTY(QColor highlightingColor READ highlightingColor WRITE setHighlightingColor)
/*! Porperty overwrite mode sets (setOverwriteMode()) or gets (overwriteMode()) the mode
in which the editor works. In overwrite mode the user will overwrite existing data. The
size of data will be constant. In insert mode the size will grow, when inserting
new data.
*/
Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode)
/*! Property selection color sets (setSelectionColor()) the backgorund
color of selected text areas. You can also read the color
(selectionColor()).
*/
Q_PROPERTY(QColor selectionColor READ selectionColor WRITE setSelectionColor)
/*! Property readOnly sets (setReadOnly()) or gets (isReadOnly) the mode
in which the editor works. In readonly mode the the user can only navigate
through the data and select data; modifying is not possible. This
property's default is false.
*/
Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
/*! Property upperCase sets (setUpperCase()) or gets (isUpperCase) the case of hex
data. Default is lowercase.
*/
Q_PROPERTY(bool upperCase READ isUpperCase WRITE setUpperCase)
/*! Set the font of the widget. Please use fixed width fonts like Mono or Courier.*/
Q_PROPERTY(QFont font READ font WRITE setFont)
public:
/*! Creates an instance of QHexEdit.
\param parent Parent widget of QHexEdit.
*/
QHexEdit(QWidget *parent=0);
// Access to data of qhexedit
/*! Sets the data of QHexEdit. The QIODevice will be opend just before reading
and closed immediately afterwards. This is to allow other programs to rewrite
the file while editing it.
*/
bool setData(QIODevice &iODevice);
/*! Givs back the data as a QByteArray starting at position \param pos and
delivering \param count bytes.
*/
QByteArray dataAt(qint64 pos, qint64 count=-1);
/*! Givs back the data into a \param iODevice starting at position \param pos
and delivering \param count bytes.
*/
bool write(QIODevice &iODevice, qint64 pos=0, qint64 count=-1);
// Char handling
/*! Inserts a char.
\param pos Index position, where to insert
\param ch Char, which is to insert
The char will be inserted and size of data grows.
*/
void insert(qint64 pos, char ch);
/*! Removes len bytes from the content.
\param pos Index position, where to remove
\param len Amount of bytes to remove
*/
void remove(qint64 pos, qint64 len=1);
/*! Replaces a char.
\param pos Index position, where to overwrite
\param ch Char, which is to insert
The char will be overwritten and size remains constant.
*/
void replace(qint64 pos, char ch);
// ByteArray handling
/*! Inserts a byte array.
\param pos Index position, where to insert
\param ba QByteArray, which is to insert
The QByteArray will be inserted and size of data grows.
*/
void insert(qint64 pos, const QByteArray &ba);
/*! Replaces \param len bytes with a byte array \param ba
\param pos Index position, where to overwrite
\param ba QByteArray, which is inserted
\param len count of bytes to overwrite
The data is overwritten and size of data may change.
*/
void replace(qint64 pos, qint64 len, const QByteArray &ba);
// Utility functioins
/*! Calc cursor position from graphics position
* \param point from where the cursor position should be calculated
* \return Cursor postioin
*/
qint64 cursorPosition(QPoint point);
/*! Ensure the cursor to be visble
*/
void ensureVisible();
/*! Find first occurence of ba in QHexEdit data
* \param ba Data to find
* \param from Point where the search starts
* \return pos if fond, else -1
*/
qint64 indexOf(const QByteArray &ba, qint64 from);
/*! Returns if any changes where done on document
* \return true when document is modified else false
*/
bool isModified();
/*! Find last occurence of ba in QHexEdit data
* \param ba Data to find
* \param from Point where the search starts
* \return pos if fond, else -1
*/
qint64 lastIndexOf(const QByteArray &ba, qint64 from);
/*! Gives back a formatted image of the selected content of QHexEdit
*/
QString selectionToReadableString();
/*! Set Font of QHexEdit
* \param font
*/
virtual void setFont(const QFont &font);
/*! Gives back a formatted image of the content of QHexEdit
*/
QString toReadableString();
public slots:
/*! Redoes the last operation. If there is no operation to redo, i.e.
there is no redo step in the undo/redo history, nothing happens.
*/
void redo();
/*! Undoes the last operation. If there is no operation to undo, i.e.
there is no undo step in the undo/redo history, nothing happens.
*/
void undo();
signals:
/*! Contains the address, where the cursor is located. */
void currentAddressChanged(qint64 address);
/*! Contains the size of the data to edit. */
void currentSizeChanged(qint64 size);
/*! The signal is emitted every time, the data is changed. */
void dataChanged();
/*! The signal is emitted every time, the overwrite mode is changed. */
void overwriteModeChanged(bool state);
/*! \cond docNever */
public:
~QHexEdit();
// Properties
bool addressArea();
void setAddressArea(bool addressArea);
QColor addressAreaColor();
void setAddressAreaColor(const QColor &color);
qint64 addressOffset();
void setAddressOffset(qint64 addressArea);
int addressWidth();
void setAddressWidth(int addressWidth);
bool asciiArea();
void setAsciiArea(bool asciiArea);
qint64 cursorPosition();
void setCursorPosition(qint64 position);
QByteArray data();
void setData(const QByteArray &ba);
bool highlighting();
void setHighlighting(bool mode);
QColor highlightingColor();
void setHighlightingColor(const QColor &color);
bool overwriteMode();
void setOverwriteMode(bool overwriteMode);
bool isReadOnly();
void setReadOnly(bool readOnly);
bool isUpperCase();
void setUpperCase(bool upperCase);
QColor selectionColor();
void setSelectionColor(const QColor &color);
protected:
// Handle events
void keyPressEvent(QKeyEvent *event);
void mouseMoveEvent(QMouseEvent * event);
void mousePressEvent(QMouseEvent * event);
void paintEvent(QPaintEvent *event);
void resizeEvent(QResizeEvent *);
private:
// Handle selections
void resetSelection(qint64 pos); // set selectionStart and selectionEnd to pos
void resetSelection(); // set selectionEnd to selectionStart
void setSelection(qint64 pos); // set min (if below init) or max (if greater init)
int getSelectionBegin();
int getSelectionEnd();
// Private utility functions
void init();
void readBuffers();
QString toReadable(const QByteArray &ba);
private slots:
void adjust(); // recalc pixel positions
void dataChangedPrivate(int idx=0); // emit dataChanged() signal
void refresh(); // ensureVisible() and readBuffers()
void updateCursor(); // update blinking cursor
private:
// Name convention: pixel positions start with _px
int _pxCharWidth, _pxCharHeight; // char dimensions (dpendend on font)
int _pxPosHexX; // X-Pos of HeaxArea
int _pxPosAdrX; // X-Pos of Address Area
int _pxPosAsciiX; // X-Pos of Ascii Area
int _pxGapAdr; // gap left from AddressArea
int _pxGapAdrHex; // gap between AddressArea and HexAerea
int _pxGapHexAscii; // gap between HexArea and AsciiArea
int _pxCursorWidth; // cursor width
int _pxSelectionSub; // offset selection rect
int _pxCursorX; // current cursor pos
int _pxCursorY; // current cursor pos
// Name convention: absolute byte positions in chunks start with _b
qint64 _bSelectionBegin; // first position of Selection
qint64 _bSelectionEnd; // end of Selection
qint64 _bSelectionInit; // memory position of Selection
qint64 _bPosFirst; // position of first byte shown
qint64 _bPosLast; // position of last byte shown
qint64 _bPosCurrent; // current position
// variables to store the property values
bool _addressArea; // left area of QHexEdit
QColor _addressAreaColor;
int _addressWidth;
bool _asciiArea;
qint64 _addressOffset;
bool _highlighting;
bool _overwriteMode;
QBrush _brushSelection;
QPen _penSelection;
QBrush _brushHighlighted;
QPen _penHighlighted;
bool _readOnly;
bool _upperCase;
// other variables
int _addrDigits; // real no of addressdigits, may be > addressWidth
bool _blink; // help get cursor blinking
QBuffer _bData; // buffer, when setup with QByteArray
Chunks *_chunks; // IODevice based access to data
QTimer _cursorTimer; // for blinking cursor
qint64 _cursorPosition; // absolute positioin of cursor, 1 Byte == 2 tics
QRect _cursorRect; // physical dimensions of cursor
QByteArray _data; // QHexEdit's data, when setup with QByteArray
QByteArray _dataShown; // data in the current View
QByteArray _hexDataShown; // data in view, transformed to hex
qint64 _lastEventSize; // size, which was emitted last time
QByteArray _markedShown; // marked data in view
bool _modified; // Is any data in editor modified?
int _rowsShown; // lines of text shown
UndoStack * _undoStack; // Stack to store edit actions for undo/redo
/*! \endcond docNever */
};
#endif // QHEXEDIT_H