├── .gitignore ├── Makefile ├── Makefile.lib ├── depends ├── license └── bsd_license.txt └── source ├── BStream.c ├── BStream.h ├── BStreamTag.c ├── BStreamTag.h ├── Base.h ├── CHash.c ├── CHash.h ├── CHash_inline.h ├── Common.c ├── Common.h ├── Common_inline.h ├── Date.c ├── Date.h ├── Duration.c ├── Duration.h ├── DynLib.c ├── DynLib.h ├── Hash_fnv.c ├── Hash_fnv.h ├── Hash_murmur.c ├── Hash_murmur.h ├── Hash_superfast.c ├── Hash_superfast.h ├── List.c ├── List.h ├── List_inline.h ├── MainArgs.c ├── MainArgs.h ├── PointerHash.c ├── PointerHash.h ├── PointerHash_inline.h ├── PointerHash_struct.h ├── PortableGettimeofday.c ├── PortableGettimeofday.h ├── PortableSnprintf.c ├── PortableSorting.c ├── PortableSorting.h ├── PortableStdint.h ├── PortableStrlcpy.c ├── PortableStrlcpy.h ├── PortableStrptime.c ├── PortableStrptime.h ├── PortableTruncate.c ├── PortableTruncate.h ├── PortableUsleep.c ├── PortableUsleep.h ├── RandomGen.c ├── RandomGen.h ├── Stack.c ├── Stack.h ├── Stack_inline.h ├── UArray.c ├── UArray.h ├── UArray_character.c ├── UArray_character.h ├── UArray_format.c ├── UArray_format.h ├── UArray_math.c ├── UArray_math.h ├── UArray_path.c ├── UArray_path.h ├── UArray_stream.c ├── UArray_stream.h ├── UArray_string.c ├── UArray_string.h ├── UArray_utf.c ├── UArray_utf.h ├── _new └── Directory.c ├── cdecode.c ├── cdecode.h ├── cencode.c ├── cencode.h ├── simd_cph ├── LICENSE.txt ├── docs │ └── LICENSE.txt ├── include │ ├── simd_cp.h │ ├── simd_cp_arm-iwmmx.h │ ├── simd_cp_emu.h │ └── simd_cp_x86.h ├── simd_cph.readme └── test │ ├── Makefile │ ├── test_simd.c │ └── test_simd_emu ├── ucs2.c ├── ucs4.c ├── utf8.c ├── utf8.h ├── utf8internal.h ├── utf_convert.c └── utf_convert.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.lib 2 | *.dll 3 | *.manifest 4 | *.obj 5 | *.exp 6 | *.ilk 7 | ._* 8 | *.pdb 9 | *.hi 10 | *.o 11 | *.so 12 | *.dylib 13 | *.cmd 14 | .mod.c* 15 | *.tmp_versions 16 | *CVS 17 | *RCS 18 | *IoVMCode.c* 19 | *Io*Init.c* 20 | ~* 21 | *_darcs 22 | *_build 23 | *_ioCodeProcessed 24 | *errors 25 | *.bak* 26 | *.BAK* 27 | *.orig* 28 | *vssver.scc* 29 | *.swp* 30 | *MT 31 | *\{arch\} 32 | *.arch-ids 33 | *, 34 | *.class* 35 | *.prof* 36 | *.DS_Store* 37 | *.FBCLockFolder 38 | *BitKeeper 39 | *ChangeSet 40 | *.svn 41 | .cvsignore* 42 | .gdb_history* 43 | *Thumbs.db* 44 | .DS_Store 45 | .libs 46 | .deps* 47 | *.a 48 | *.la 49 | *.lo 50 | *.so 51 | *.dylib 52 | *.exe 53 | *.Po 54 | *.Tlo 55 | *.Plo 56 | _objs 57 | _includes 58 | *_libs 59 | *Io.*Code.c* 60 | io2c 61 | *Io.*Init.c* 62 | *pngtest* 63 | *steve.model* 64 | *skipdbtest* 65 | *config.log* 66 | *config.status* 67 | .rej* 68 | *autom4te.cache* 69 | *.cache 70 | *_include 71 | *tags* 72 | ./addons/SGML/source/libsgml/Makefile* 73 | ./addons/SGML/source/libsgml/examples/Makefile* 74 | ./addons/SGML/source/libsgml/src/Makefile* 75 | tools/editlib_test/editlib_test 76 | extras/IoPlayers/MSWindows/ioplayer/ioplayer.ncb 77 | extras/IoPlayers/MSWindows/ioplayer/ioplayer.suo 78 | extras/IoPlayers/MSWindows/ioplayer/ioplayer/Debug 79 | extras/IoPlayers/MSWindows/ioplayer/ioplayer/Release 80 | extras/IoPlayers/MSWindows/ioplayer/ioplayer/ioplayer.vcproj.CUSTOMER2007.Customer.user 81 | extras/IoPlayers/MSWindows/ioplayer/pingme.txt 82 | extras/IoPlayers/MSWindows/ioplayer/smysrv 83 | libs/iovm/docs/docs.txt 84 | addons/*/docs/docs.txt 85 | *.mode1 86 | *.pbxuser 87 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include Makefile.lib 2 | CFLAGS += -DBUILDING_BASEKIT_DLL $(IOVMALLFLAGS) 3 | CFLAGS += -Isource/simd_cph/include 4 | -------------------------------------------------------------------------------- /Makefile.lib: -------------------------------------------------------------------------------- 1 | ifeq ($(shell [ -f Makefile.local ] && echo true),true) 2 | ALL_BEGIN := $(MAKE) -f Makefile.local all_begin 3 | ALL_END := $(MAKE) -f Makefile.local all_end 4 | MAKE_LOCAL_CLEAN := $(MAKE) -f Makefile.local clean 5 | else 6 | ALL_BEGIN := 7 | ALL_END := 8 | MAKE_LOCAL_CLEAN := 9 | endif 10 | 11 | #CC ?= g++ 12 | 13 | RANLIB ?= ranlib 14 | AR ?= ar 15 | ARFLAGS := rcu 16 | AROUTFLAG := 17 | CCOUTFLAG := -o 18 | LINKDLL := $(CC) 19 | LINKDLLOUTFLAG := -o 20 | LINKDIRFLAG := -L 21 | LINKLIBFLAG := -l 22 | INSTALL_PREFIX_DEFINE := $(INSTALL_PREFIX) 23 | 24 | # may need to remove --param max-inline-insns-single=500 for older versions of gccs 25 | WARN :=-Wstrict-prototypes 26 | #-Winline 27 | #--param max-inline-insns-single=500 28 | 29 | #-ansi -pedantic 30 | OPTIMIZE :=-O3 -g 31 | #-msse2 -msse -mmmx 32 | #OPTIMIZE :=-O3 -ffast-math -ftree-vectorize -ftree-vectorizer-verbose=4 33 | DLL_SUFFIX := so 34 | DLL_COMMAND := -shared 35 | FLAT_NAMESPACE := 36 | dependson := $(shell cat depends) 37 | 38 | HEADERS :=-I. -I./source 39 | others := $(dependson) 40 | others := $(addprefix -I../,$(others)) 41 | others := $(addsuffix /_build/headers,$(others)) 42 | HEADERS += $(others) 43 | 44 | DLL_L := $(dependson) 45 | DLL_L := $(addprefix -L../,$(DLL_L)) 46 | DLL_L := $(addsuffix /_build/dll,$(DLL_L)) 47 | 48 | DLL_l := $(dependson) 49 | DLL_l := $(addprefix -l,$(DLL_l)) 50 | 51 | CFLAGS = $(OPTIMIZE) $(WARN) $(HEADERS) #--param max-inline-insns-single=500 52 | 53 | # Uncommment for Coros to register their stack with Valgrind 54 | #CFLAGS += -DUSE_VALGRIND 55 | 56 | ### PLATFORM ##################################################### 57 | 58 | SYS ?= $(shell uname -s) 59 | 60 | ifeq ($(SYS),Darwin) 61 | CFLAGS += -falign-loops=16 62 | CFLAGS += -fPIC 63 | DLL_SUFFIX := dylib 64 | DLL_COMMAND := -dynamiclib 65 | FLAT_NAMESPACE := -flat_namespace 66 | endif 67 | 68 | ifeq ($(SYS),DragonFly) 69 | LFLAGS += -lm 70 | endif 71 | 72 | ifeq ($(SYS),Linux) 73 | CFLAGS += -falign-loops=16 74 | CFLAGS += -fPIC 75 | endif 76 | 77 | ifeq ($(SYS),IRIX) 78 | RANLIB ?= touch 79 | endif 80 | 81 | ifneq (,$(findstring CYGW,$(SYS))) 82 | DLL_SUFFIX := dll 83 | endif 84 | 85 | ifneq (,$(findstring MINGW,$(SYS))) 86 | DLL_SUFFIX := dll 87 | endif 88 | 89 | ifneq (,$(findstring Windows,$(SYS))) 90 | CC := cl -nologo 91 | CCOUTFLAG :=-Fo 92 | WARN := 93 | #OPTIMIZE :=-Zi -MDd -D_USE_MATH_DEFINES -DWIN32 -D_DEBUG -D_CRT_SECURE_NO_DEPRECATE 94 | OPTIMIZE :=-O2 -EHsc -MD -D_USE_MATH_DEFINES -DWIN32 -DNDEBUG -D_CRT_SECURE_NO_DEPRECATE 95 | AR := link -lib 96 | AROUTFLAG :=-out: 97 | ARFLAGS := 98 | LINKDLL := link 99 | LINKDLLOUTFLAG :=-out: 100 | LINKDIRFLAG := -libpath: 101 | LINKLIBFLAG := 102 | DLL_LIB_SUFFIX := .lib 103 | DLL_LIB_PREFIX := 104 | DLL_COMMAND := -link /INCREMENTAL:NO -subsystem:WINDOWS -machine:X86 -DLL $(DEF_FILE) 105 | DLL_SUFFIX := dll 106 | DLL_EXTRAS := ws2_32.lib shell32.lib 107 | FLAT_NAMESPACE := 108 | RANLIB := echo no ranlib 109 | INSTALL_PREFIX_DEFINE := $(shell cygpath -am $(INSTALL_PREFIX)) 110 | endif 111 | 112 | ### FILES ######################################################### 113 | 114 | NAME := $(notdir $(subst $() ,_,$(shell pwd))) 115 | LIBR := _build/lib/lib$(NAME).a 116 | DLL := _build/dll/lib$(NAME).$(DLL_SUFFIX) 117 | infiles := $(wildcard source/*.c) 118 | #infiles += $(wildcard *.S) 119 | asmfiles := $(wildcard source/*.S) 120 | hfiles := $(wildcard source/*.h) 121 | buildhfiles := $(subst source/,_build/headers/,$(hfiles)) 122 | objects := $(notdir $(infiles)) 123 | objects := $(basename $(objects)) 124 | objects := $(addsuffix .o,$(objects)) 125 | objects := $(addprefix _build/objs/,$(objects)) 126 | 127 | vmall_objects := $(notdir $(infiles)) 128 | vmall_objects := $(basename $(vmall_objects)) 129 | vmall_objects := $(addsuffix .o,$(vmall_objects)) 130 | vmall_objects := $(addprefix _build/vmall_objs/,$(vmall_objects)) 131 | 132 | 133 | DLL_L := $(dependson) 134 | DLL_L := $(addprefix $(LINKDIRFLAG)../,$(DLL_L)) 135 | DLL_L := $(addsuffix /_build/dll,$(DLL_L)) 136 | 137 | DLL_l := $(dependson) 138 | DLL_l := $(addprefix $(LINKLIBFLAG),$(DLL_l)) 139 | DLL_l := $(addsuffix $(DLL_LIB_SUFFIX),$(DLL_l)) 140 | 141 | DEF_FILE := 142 | 143 | ### RULES ########################################################### 144 | 145 | all: _build/objs _build/headers _build/lib _build/dll $(buildhfiles) 146 | $(ALL_BEGIN) 147 | $(MAKE) $(LIBR) 148 | $(MAKE) $(DLL) 149 | ifneq (,$(findstring Windows,$(SYS))) 150 | mkdir -p _build/vmall_objs 151 | $(MAKE) vmall_objs 152 | endif 153 | $(ALL_END) 154 | 155 | _build: 156 | mkdir -p $@ 157 | 158 | _build/objs: _build 159 | mkdir -p $@ 160 | 161 | _build/headers: _build 162 | mkdir -p $@ 163 | 164 | _build/lib: _build 165 | mkdir -p $@ 166 | 167 | _build/dll: _build 168 | mkdir -p $@ 169 | 170 | # pull in dependency info for *existing* .o files 171 | -include $(objects:.o=.d) 172 | 173 | _build/objs/%.o: source/%.c 174 | ifeq (,$(findstring Windows,$(SYS))) 175 | $(CC) -MM -MT $@ -MF $(@:.o=.d) -DINSTALL_PREFIX=\"$(INSTALL_PREFIX_DEFINE)\" $(CFLAGS) -c $< $(CCOUTFLAG)$@ 176 | endif 177 | $(CC) -DINSTALL_PREFIX=\"$(INSTALL_PREFIX_DEFINE)\" $(CFLAGS) -c $< $(CCOUTFLAG)$@ 178 | 179 | _build/vmall_objs/%.o: source/%.c 180 | $(CC) -DINSTALL_PREFIX=\"$(INSTALL_PREFIX_DEFINE)\" $(CFLAGS) \ 181 | -DBUILDING_IOVMALL_DLL -c $< $(CCOUTFLAG)$@ 182 | 183 | _build/headers/%.h: source/%.h _build/headers 184 | cp $< $@ 185 | 186 | _build/vmall_objs: 187 | mkdir -p $@ 188 | 189 | vmall_objs: _build/vmall_objs $(vmall_objects) 190 | 191 | $(LIBR): $(objects) 192 | ifneq ($(asmfiles),) 193 | $(CC) $(CFLAGS) -c $(asmfiles) $(CCOUTFLAG)_build/objs/asm.o || true 194 | endif 195 | $(AR) $(ARFLAGS) $(AROUTFLAG)$@ _build/objs/*.o 196 | $(RANLIB) $@ 197 | 198 | $(DLL): $(objects) 199 | $(LINKDLL) $(DLL_COMMAND) $(FLAT_NAMESPACE) $(DLL_L) _build/objs/*.o $(LINKDLLOUTFLAG)$(DLL) $(DLL_l) $(DLL_EXTRAS) 200 | ifneq (,$(findstring Windows,$(SYS))) 201 | mt.exe -manifest $@.manifest -outputresource:$@ 202 | rm $@.manifest 203 | endif 204 | 205 | clean: 206 | rm -rf _build 207 | $(MAKE_LOCAL_CLEAN) 208 | 209 | -------------------------------------------------------------------------------- /depends: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevedekorte/basekit/a3e54ba83b85f530dc9442a33d2779240ed96189/depends -------------------------------------------------------------------------------- /license/bsd_license.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevedekorte/basekit/a3e54ba83b85f530dc9442a33d2779240ed96189/license/bsd_license.txt -------------------------------------------------------------------------------- /source/BStream.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright 3 | Steve Dekorte, 2004 4 | license 5 | BSD revised 6 | description 7 | A Binary Stream that supports tagged items. 8 | */ 9 | 10 | #ifndef BSTREAM_DEFINED 11 | #define BSTREAM_DEFINED 1 12 | 13 | #include "Common.h" 14 | #include "UArray.h" 15 | #include "BStreamTag.h" 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | //typedef struct UArray UArray; 22 | 23 | typedef struct 24 | { 25 | UArray *ba; 26 | size_t index; 27 | unsigned char ownsUArray; 28 | UArray *tmp; 29 | UArray *errorBa; 30 | int flipEndian; 31 | unsigned char *typeBuf; 32 | } BStream; 33 | 34 | /* 35 | #define BStream_ba_(self, v) self->ba = v; 36 | #define BStream_ba(self) (self->ba) 37 | 38 | #define BStream_index_(self, v) self->index = v; 39 | #define BStream_index(self) (self->index) 40 | 41 | #define BStream_ownsUArray_(self, v) self->ownsUArray = v; 42 | #define BStream_ownsUArray(self) (self->ownsUArray) 43 | 44 | #define BStream_tmp_(self, v) self->tmp = v; 45 | #define BStream_tmp(self) (self->tmp) 46 | 47 | #define BStream_errorBa_(self, v) self->errorBa = v; 48 | #define BStream_errorBa(self) (self->errorBa) 49 | 50 | #define BStream_flipEndian_(self, v) self->flipEndian = v; 51 | #define BStream_flipEndian(self) (self->flipEndian) 52 | 53 | #define BStream_typeBuf_(self, v) self->typeBuf = v; 54 | #define BStream_typeBufs(self) (self->typeBuf) 55 | */ 56 | 57 | BASEKIT_API BStream *BStream_new(void); 58 | BASEKIT_API BStream *BStream_clone(BStream *self); 59 | BASEKIT_API void BStream_free(BStream *self); 60 | 61 | BASEKIT_API char *BStream_errorString(BStream *self); 62 | BASEKIT_API void BStream_setUArray_(BStream *self, UArray *ba); 63 | BASEKIT_API void BStream_setData_length_(BStream *self, unsigned char *data, size_t length); 64 | BASEKIT_API UArray *BStream_byteArray(BStream *self); 65 | BASEKIT_API void BStream_empty(BStream *self); 66 | BASEKIT_API int BStream_isEmpty(BStream *self); 67 | 68 | // writing -------------------------------------- 69 | 70 | BASEKIT_API void BStream_writeByte_(BStream *self, unsigned char v); 71 | 72 | BASEKIT_API void BStream_writeUint8_(BStream *self, uint8_t v); 73 | BASEKIT_API void BStream_writeUint32_(BStream *self, uint32_t v); 74 | BASEKIT_API void BStream_writeInt32_(BStream *self, int32_t v); 75 | #if !defined(__SYMBIAN32__) 76 | BASEKIT_API void BStream_writeInt64_(BStream *self, int64_t v); 77 | #endif 78 | BASEKIT_API void BStream_writeDouble_(BStream *self, double v); 79 | BASEKIT_API void BStream_writeData_length_(BStream *self, const unsigned char *data, size_t length); 80 | BASEKIT_API void BStream_writeCString_(BStream *self, const char *s); 81 | BASEKIT_API void BStream_writeUArray_(BStream *self, UArray *ba); 82 | 83 | // reading -------------------------------------- 84 | 85 | BASEKIT_API unsigned char BStream_readByte(BStream *self); 86 | 87 | BASEKIT_API uint8_t BStream_readUint8(BStream *self); 88 | BASEKIT_API uint32_t BStream_readUint32(BStream *self); 89 | BASEKIT_API int32_t BStream_readInt32(BStream *self); 90 | #if !defined(__SYMBIAN32__) 91 | BASEKIT_API int64_t BStream_readInt64(BStream *self); 92 | #endif 93 | BASEKIT_API double BStream_readDouble(BStream *self); 94 | BASEKIT_API uint8_t *BStream_readDataOfLength_(BStream *self, size_t length); 95 | BASEKIT_API void BStream_readUArray_(BStream *self, UArray *b); 96 | BASEKIT_API UArray *BStream_readUArray(BStream *self); 97 | BASEKIT_API const char *BStream_readCString(BStream *self); 98 | 99 | // tagged writing -------------------------------------- 100 | 101 | BASEKIT_API void BStream_writeTaggedUint8_(BStream *self, uint8_t v); 102 | BASEKIT_API void BStream_writeTaggedUint32_(BStream *self, uint32_t v); 103 | BASEKIT_API void BStream_writeTaggedInt32_(BStream *self, int32_t v); 104 | #if !defined(__SYMBIAN32__) 105 | BASEKIT_API void BStream_writeTaggedInt64_(BStream *self, int64_t v); 106 | #endif 107 | BASEKIT_API void BStream_writeTaggedDouble_(BStream *self, double v); 108 | BASEKIT_API void BStream_writeTaggedData_length_(BStream *self, const unsigned char *data, size_t length); 109 | BASEKIT_API void BStream_writeTaggedCString_(BStream *self, const char *s); 110 | BASEKIT_API void BStream_writeTaggedUArray_(BStream *self, UArray *ba); 111 | 112 | // tagged reading -------------------------------------- 113 | 114 | BASEKIT_API uint8_t BStream_readTaggedUint8(BStream *self); 115 | BASEKIT_API uint32_t BStream_readTaggedUint32(BStream *self); 116 | BASEKIT_API int32_t BStream_readTaggedInt32(BStream *self); 117 | #if !defined(__SYMBIAN32__) 118 | BASEKIT_API int64_t BStream_readTaggedInt64(BStream *self); 119 | #endif 120 | BASEKIT_API double BStream_readTaggedDouble(BStream *self); 121 | BASEKIT_API void BStream_readTaggedUArray_(BStream *self, UArray *b); 122 | BASEKIT_API UArray *BStream_readTaggedUArray(BStream *self); 123 | BASEKIT_API const char *BStream_readTaggedCString(BStream *self); 124 | 125 | BASEKIT_API void BStream_show(BStream *self); 126 | 127 | #ifdef __cplusplus 128 | } 129 | #endif 130 | #endif 131 | 132 | -------------------------------------------------------------------------------- /source/BStreamTag.c: -------------------------------------------------------------------------------- 1 | /* 2 | copyright 3 | Steve Dekorte, 2004 4 | license 5 | BSD revised 6 | */ 7 | 8 | #include "BStreamTag.h" 9 | #include 10 | 11 | /* 12 | unsigned int isArray : 1; 13 | unsigned int type : 2; 14 | unsigned int byteCount : 5; 15 | */ 16 | 17 | BStreamTag BStreamTag_FromUnsignedChar(unsigned char c) 18 | { 19 | // we need to do this because bit fields are compiler dependent 20 | BStreamTag t; 21 | t.isArray = c >> 7; 22 | t.type = ( c << 1) >> 6; 23 | t.byteCount = ( c << 3 ) >> 3; 24 | return t; 25 | } 26 | 27 | unsigned char BStreamTag_asUnsignedChar(BStreamTag *self) 28 | { 29 | BStreamTag t = *self; 30 | unsigned char c = 0; 31 | c = c | t.isArray << 7; 32 | c = c | t.type << 5; 33 | c = c | t.byteCount; 34 | return c; 35 | } 36 | 37 | // ----------------------------------------------------- 38 | 39 | BStreamTag BStreamTag_TagArray_type_byteCount_(unsigned int a, unsigned int t, unsigned int b) 40 | { 41 | BStreamTag self; 42 | self.isArray = a; 43 | self.type = t; 44 | self.byteCount = b; 45 | return self; 46 | } 47 | 48 | int BStreamTag_isEqual_(BStreamTag *self, BStreamTag *other) 49 | { 50 | return (BStreamTag_asUnsignedChar(self) == BStreamTag_asUnsignedChar(other)); 51 | } 52 | 53 | void BStreamTag_print(BStreamTag *self) 54 | { 55 | printf("[Tag "); 56 | printf("isArray: %i ", self->isArray); 57 | printf("type: %i ", self->type); 58 | printf("byteCount: %i", self->byteCount); 59 | printf("]"); 60 | } 61 | 62 | char *BStreamTag_typeName(BStreamTag *self) 63 | { 64 | switch (self->type) 65 | { 66 | case BSTREAM_UNSIGNED_INT: 67 | return "uint"; 68 | case BSTREAM_SIGNED_INT: 69 | return "int"; 70 | case BSTREAM_FLOAT: 71 | return "float"; 72 | case BSTREAM_POINTER: 73 | return "pointer"; 74 | } 75 | 76 | return "UNKNOWN TYPE"; 77 | } 78 | -------------------------------------------------------------------------------- /source/BStreamTag.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright 3 | Steve Dekorte, 2004 4 | license 5 | BSD revised 6 | */ 7 | 8 | #ifndef BSTREAMTAG_DEFINED 9 | #define BSTREAMTAG_DEFINED 1 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #define BSTREAM_UNSIGNED_INT 0 16 | #define BSTREAM_SIGNED_INT 1 17 | #define BSTREAM_FLOAT 2 18 | #define BSTREAM_POINTER 3 19 | 20 | typedef struct 21 | { 22 | unsigned int isArray : 1; 23 | unsigned int type : 2; // 0 = unsigned int, 1 = signed int, 2 = float, 3 = pointer 24 | unsigned int byteCount : 5; // number of bytes in data value(s) 25 | } BStreamTag; 26 | 27 | // values in network byte order / big endian 28 | 29 | BStreamTag BStreamTag_FromUnsignedChar(unsigned char c); 30 | unsigned char BStreamTag_asUnsignedChar(BStreamTag *self); 31 | BStreamTag BStreamTag_TagArray_type_byteCount_(unsigned int a, unsigned int t, unsigned int b); 32 | int BStreamTag_isEqual_(BStreamTag *self, BStreamTag *other); 33 | void BStreamTag_print(BStreamTag *self); 34 | 35 | char *BStreamTag_typeName(BStreamTag *self); 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | #endif 41 | 42 | -------------------------------------------------------------------------------- /source/Base.h: -------------------------------------------------------------------------------- 1 | #ifndef IOBASE_DEFINED 2 | #define IOBASE_DEFINED 1 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /source/CHash.c: -------------------------------------------------------------------------------- 1 | //metadoc CHash copyright Steve Dekorte 2009 2 | //metadoc CHash license BSD revised 3 | //metadoc CHash notes Suggestion to use cuckoo hash and original implementation by Marc Fauconneau 4 | 5 | #define CHASH_C 6 | #include "CHash.h" 7 | #undef CHASH_C 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | CHash *CHash_new(void) 14 | { 15 | CHash *self = (CHash *)io_calloc(1, sizeof(CHash)); 16 | CHash_setSize_(self, 8); 17 | return self; 18 | } 19 | 20 | void CHash_copy_(CHash *self, const CHash *other) 21 | { 22 | io_free(self->records); 23 | memcpy(self, other, sizeof(CHash)); 24 | self->records = malloc(self->size * sizeof(CHashRecord)); 25 | memcpy(self->records, other->records, self->size * sizeof(CHashRecord)); 26 | } 27 | 28 | CHash *CHash_clone(CHash *self) 29 | { 30 | CHash *other = CHash_new(); 31 | CHash_copy_(other, self); 32 | return other; 33 | } 34 | 35 | void CHash_setSize_(CHash *self, size_t size) 36 | { 37 | self->records = realloc(self->records, size * sizeof(CHashRecord)); 38 | 39 | if(size > self->size) 40 | { 41 | memset(self->records + self->size * sizeof(CHashRecord), 42 | 0x0, (size - self->size) * sizeof(CHashRecord)); 43 | } 44 | 45 | self->size = size; 46 | 47 | CHash_updateMask(self); 48 | //CHash_show(self); 49 | } 50 | 51 | void CHash_updateMask(CHash *self) 52 | { 53 | self->mask = (intptr_t)(self->size - 1); 54 | } 55 | 56 | void CHash_show(CHash *self) 57 | { 58 | size_t i; 59 | 60 | printf("CHash records:\n"); 61 | for(i = 0; i < self->size; i++) 62 | { 63 | CHashRecord *r = CRecords_recordAt_(self->records, i); 64 | printf(" %i: %p %p\n", (int)i, r->k, r->v); 65 | } 66 | } 67 | 68 | void CHash_free(CHash *self) 69 | { 70 | io_free(self->records); 71 | io_free(self); 72 | } 73 | 74 | void CHash_setHash1Func_(CHash *self, CHashHashFunc *f) 75 | { 76 | self->hash1 = f; 77 | } 78 | 79 | void CHash_setHash2Func_(CHash *self, CHashHashFunc *f) 80 | { 81 | self->hash2 = f; 82 | } 83 | 84 | void CHash_setEqualFunc_(CHash *self, CHashEqualFunc *f) 85 | { 86 | self->equals = f; 87 | } 88 | 89 | int CHash_insert_(CHash *self, CHashRecord *x) 90 | { 91 | int n; 92 | 93 | for (n = 0; n < CHASH_MAXLOOP; n ++) 94 | { 95 | CHashRecord *r; 96 | 97 | //pos = self->hash1(x->k) & self->mask; 98 | //printf("1 x->k = %p-> %i\n", x->k, pos); 99 | r = CHash_record1_(self, x->k); 100 | CHashRecord_swapWith_(x, r); //x ↔ T1 [h1 (x)] 101 | if(x->k == 0x0) { self->keyCount ++; return 0; } 102 | 103 | //pos = self->hash2(x->k) & self->mask; 104 | //printf("2 x->k = %p-> %i\n\n", x->k, pos); 105 | r = CHash_record2_(self, x->k); 106 | CHashRecord_swapWith_(x, r); //x ↔ T2 [h2 (x)] 107 | if(x->k == 0x0) { self->keyCount ++; return 0; } 108 | } 109 | 110 | if(self->isResizing) 111 | { 112 | return -1; 113 | } 114 | 115 | CHash_grow(self); 116 | CHash_at_put_(self, x->k, x->v); 117 | return 0; 118 | } 119 | 120 | int CHash_insertRecords(CHash *self, unsigned char *oldRecords, size_t oldSize) 121 | { 122 | size_t i; 123 | 124 | for (i = 0; i < oldSize; i ++) 125 | { 126 | CHashRecord *r = CRecords_recordAt_(oldRecords, i); 127 | 128 | if (r->k) 129 | { 130 | if(CHash_at_put_(self, r->k, r->v)) return 1; 131 | } 132 | } 133 | return 0; 134 | } 135 | 136 | int CHash_resizeTo_(CHash *self, size_t newSize) 137 | { 138 | unsigned char *oldRecords = self->records; 139 | size_t oldSize = self->size; 140 | 141 | self->isResizing = 1; 142 | 143 | //printf("%p resizeTo %i/%i %i%%\n", (void *)self, self->keyCount, self->size, (int)(100.0*CHash_density(self))); 144 | 145 | do 146 | { 147 | self->size = newSize; 148 | self->records = io_calloc(1, sizeof(CHashRecord) * self->size); 149 | self->keyCount = 0; 150 | CHash_updateMask(self); 151 | if(CHash_insertRecords(self, oldRecords, oldSize) == 0) 152 | { 153 | self->isResizing = 0; 154 | } 155 | else 156 | { 157 | //printf("%p grow collision %i/%i\n", (void *)self, self->keyCount, self->size); 158 | newSize *= 2; 159 | io_free(self->records); 160 | } 161 | } while(self->isResizing); 162 | 163 | io_free(oldRecords); 164 | return 0; 165 | } 166 | 167 | void CHash_grow(CHash *self) 168 | { 169 | CHash_resizeTo_(self, self->size * 2); 170 | } 171 | 172 | void CHash_shrink(CHash *self) 173 | { 174 | //printf("%p shrink %i/%i\n", (void *)self, self->keyCount, self->size); 175 | //CHash_resizeTo_(self, self->size / 2); 176 | } 177 | 178 | void CHash_removeKey_(CHash *self, void *k) 179 | { 180 | CHashRecord *r1 = CHash_record1_(self, k); 181 | CHashRecord *r2; 182 | 183 | if(r1->k && self->equals(k, r1->k)) 184 | { 185 | r1->k = 0x0; 186 | r1->v = 0x0; 187 | self->keyCount --; 188 | CHash_shrinkIfNeeded(self); 189 | return; 190 | } 191 | 192 | r2 = CHash_record2_(self, k); 193 | 194 | if(r2->k && self->equals(k, r2->k)) 195 | { 196 | r2->k = 0x0; 197 | r2->v = 0x0; 198 | self->keyCount --; 199 | CHash_shrinkIfNeeded(self); 200 | return; 201 | } 202 | } 203 | 204 | void CHash_clear(CHash *self) 205 | { 206 | memset(self->records, 0x0, self->size * sizeof(CHashRecord)); 207 | self->keyCount = 0; 208 | CHash_shrinkIfNeeded(self); 209 | } 210 | 211 | size_t CHash_size(CHash *self) // actually the keyCount 212 | { 213 | return self->keyCount; 214 | } 215 | 216 | // ---------------------------- 217 | 218 | size_t CHash_memorySize(CHash *self) 219 | { 220 | return sizeof(CHash) + self->size * sizeof(CHashRecord); 221 | } 222 | 223 | void CHash_compact(CHash *self) 224 | { 225 | } 226 | 227 | float CHash_density(CHash *self) 228 | { 229 | float kc = (float)self->keyCount; 230 | float size = (float)self->size; 231 | return kc/size; 232 | } 233 | 234 | -------------------------------------------------------------------------------- /source/CHash.h: -------------------------------------------------------------------------------- 1 | //metadoc CHash copyright Steve Dekorte 2009 2 | //metadoc CHash license BSD revised 3 | 4 | #ifndef CHASH_DEFINED 5 | #define CHASH_DEFINED 1 6 | 7 | #include "Common.h" 8 | #include 9 | #include "PortableStdint.h" 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #define CHASH_MAXLOOP 5 16 | 17 | typedef int (CHashEqualFunc)(void *, void *); 18 | typedef intptr_t (CHashHashFunc)(void *); 19 | 20 | typedef struct 21 | { 22 | void *k; 23 | void *v; 24 | } CHashRecord; 25 | 26 | typedef struct 27 | { 28 | unsigned char *records; 29 | size_t size; 30 | size_t keyCount; 31 | CHashHashFunc *hash1; 32 | CHashHashFunc *hash2; 33 | CHashEqualFunc *equals; 34 | intptr_t mask; 35 | int isResizing; 36 | } CHash; 37 | 38 | BASEKIT_API CHash *CHash_new(void); 39 | BASEKIT_API void CHash_copy_(CHash *self, const CHash *other); 40 | BASEKIT_API CHash *CHash_clone(CHash *self); 41 | BASEKIT_API void CHash_free(CHash *self); 42 | 43 | BASEKIT_API void CHash_setHash1Func_(CHash *self, CHashHashFunc *f); 44 | BASEKIT_API void CHash_setHash2Func_(CHash *self, CHashHashFunc *f); 45 | BASEKIT_API void CHash_setEqualFunc_(CHash *self, CHashEqualFunc *f); 46 | 47 | BASEKIT_API void CHash_removeKey_(CHash *self, void *k); 48 | BASEKIT_API void CHash_clear(CHash *self); 49 | BASEKIT_API size_t CHash_size(CHash *self); // actually the keyCount 50 | 51 | BASEKIT_API size_t CHash_memorySize(CHash *self); 52 | BASEKIT_API void CHash_compact(CHash *self); 53 | 54 | // private methods ------------------------------- 55 | 56 | BASEKIT_API void CHash_setSize_(CHash *self, size_t size); 57 | BASEKIT_API int CHash_insert_(CHash *self, CHashRecord *x); 58 | BASEKIT_API void CHash_grow(CHash *self); 59 | BASEKIT_API void CHash_shrink(CHash *self); 60 | BASEKIT_API void CHash_show(CHash *self); 61 | BASEKIT_API void CHash_updateMask(CHash *self); 62 | BASEKIT_API float CHash_density(CHash *self); 63 | 64 | #include "CHash_inline.h" 65 | 66 | 67 | #ifdef __cplusplus 68 | } 69 | #endif 70 | #endif 71 | -------------------------------------------------------------------------------- /source/CHash_inline.h: -------------------------------------------------------------------------------- 1 | //metadoc CHash copyright Steve Dekorte 2009 2 | //metadoc CHash license BSD revised 3 | /*metadoc CHash description 4 | CHash - Cuckoo Hash 5 | keys and values are references (they are not copied or freed) 6 | */ 7 | 8 | #ifdef CHASH_C 9 | #define IO_IN_C_FILE 10 | #endif 11 | #include "Common_inline.h" 12 | #ifdef IO_DECLARE_INLINES 13 | 14 | #define CRecords_recordAt_(records, pos) (CHashRecord *)(records + (pos * sizeof(CHashRecord))) 15 | 16 | IOINLINE CHashRecord *CHash_record1_(CHash *self, void *k) 17 | { 18 | // the ~ | 0x1 before the mask ensures an even pos 19 | size_t pos = self->hash1(k) & self->mask; 20 | //printf("pos1 %i/%i\n", pos, self->size); 21 | return CRecords_recordAt_(self->records, pos); 22 | } 23 | 24 | IOINLINE CHashRecord *CHash_record2_(CHash *self, void *k) 25 | { 26 | // the | 0x1 before the mask ensures an odd pos 27 | size_t pos = self->hash2(k) & self->mask; 28 | //printf("pos2 %i/%i\n", pos, self->size); 29 | return CRecords_recordAt_(self->records, pos); 30 | } 31 | 32 | IOINLINE void *CHash_at_(CHash *self, void *k) 33 | { 34 | CHashRecord *r; 35 | 36 | r = CHash_record1_(self, k); 37 | 38 | if(r->k && self->equals(k, r->k)) 39 | { 40 | return r->v; 41 | } 42 | 43 | r = CHash_record2_(self, k); 44 | 45 | if(r->k && self->equals(k, r->k)) 46 | { 47 | return r->v; 48 | } 49 | 50 | return 0x0; 51 | } 52 | 53 | IOINLINE size_t CHash_count(CHash *self) 54 | { 55 | return self->keyCount; 56 | } 57 | 58 | IOINLINE int CHashKey_hasKey_(CHash *self, void *key) 59 | { 60 | return CHash_at_(self, key) != NULL; 61 | } 62 | 63 | IOINLINE int CHash_at_put_(CHash *self, void *k, void *v) 64 | { 65 | CHashRecord *r; 66 | 67 | r = CHash_record1_(self, k); 68 | 69 | if(!r->k) 70 | { 71 | r->k = k; 72 | r->v = v; 73 | self->keyCount ++; 74 | return 0; 75 | } 76 | 77 | if(k == r->k || self->equals(k, r->k)) 78 | { 79 | r->v = v; 80 | return 0; 81 | } 82 | 83 | r = CHash_record2_(self, k); 84 | 85 | if(!r->k) 86 | { 87 | r->k = k; 88 | r->v = v; 89 | self->keyCount ++; 90 | return 0; 91 | } 92 | 93 | if(k == r->k || self->equals(k, r->k)) 94 | { 95 | r->v = v; 96 | return 0; 97 | } 98 | 99 | 100 | { 101 | CHashRecord x; 102 | x.k = k; 103 | x.v = v; 104 | return CHash_insert_(self, &x); 105 | } 106 | } 107 | 108 | IOINLINE void CHash_shrinkIfNeeded(CHash *self) 109 | { 110 | if(self->keyCount < self->size/5) 111 | { 112 | CHash_shrink(self); 113 | } 114 | } 115 | 116 | IOINLINE void CHashRecord_swapWith_(CHashRecord *self, CHashRecord *other) 117 | { 118 | CHashRecord tmp = *self; 119 | *self = *other; 120 | *other = tmp; 121 | } 122 | 123 | IOINLINE void CHash_clean(CHash *self) 124 | { 125 | memset(self->records, 0, sizeof(CHashRecord) * self->size); 126 | self->keyCount = 0; 127 | } 128 | 129 | // --- enumeration -------------------------------------------------- 130 | 131 | #define CHASH_FOREACH(self, pkey, pvalue, code) \ 132 | {\ 133 | CHash *_self = (self);\ 134 | unsigned char *_records = _self->records;\ 135 | unsigned int _i, _size = _self->size;\ 136 | void *pkey;\ 137 | void *pvalue;\ 138 | \ 139 | for (_i = 0; _i < _size; _i ++)\ 140 | {\ 141 | CHashRecord *_record = CRecords_recordAt_(_records, _i);\ 142 | if (_record->k)\ 143 | {\ 144 | pkey = _record->k;\ 145 | pvalue = _record->v;\ 146 | code;\ 147 | }\ 148 | }\ 149 | } 150 | 151 | #undef IO_IN_C_FILE 152 | #endif 153 | -------------------------------------------------------------------------------- /source/Common.c: -------------------------------------------------------------------------------- 1 | //metadoc Common copyright Steve Dekorte 2002 2 | //metadoc Common license BSD revised 3 | 4 | #include "Common.h" 5 | #include 6 | 7 | #ifdef IO_CHECK_ALLOC 8 | 9 | static long allocs = 0; 10 | static long reallocs = 0; 11 | static long allocatedBytes = 0; 12 | static long maxAllocatedBytes = 0; 13 | static long frees = 0; 14 | 15 | /* 16 | typedef struct 17 | { 18 | long allocs = 0; 19 | long reallocs = 0; 20 | long allocatedBytes = 0; 21 | long maxAllocatedBytes = 0; 22 | long frees = 0; 23 | } Allocator; 24 | 25 | Allocator *Allocator_new(void) 26 | { 27 | Allocator *self = calloc(1, sizeof(Allocator)); 28 | return self; 29 | } 30 | 31 | void Allocator_free(Allocator *self) 32 | { 33 | free(self); 34 | } 35 | 36 | size_t Allocator_allocs(Allocator *self) 37 | { 38 | return self->allocs; 39 | } 40 | 41 | size_t Allocator_frees(Allocator *self) 42 | { 43 | return self->frees; 44 | } 45 | 46 | size_t Allocator_allocatedBytes(Allocator *self) 47 | { 48 | return self->allocatedBytes; 49 | } 50 | 51 | size_t Allocator_maxAllocatedBytes(Allocator *self) 52 | { 53 | return self->maxAllocatedBytes; 54 | } 55 | 56 | void Allocator_resetMaxAllocatedBytes(Allocator *self) 57 | { 58 | self->maxAllocatedBytes = self->allocatedBytes; 59 | } 60 | 61 | void Allocator_show(Allocator *self) 62 | { 63 | printf("allocs %i\n", self->allocs); 64 | printf("reallocs %i\n", self->reallocs); 65 | printf("frees %i\n", self->frees); 66 | printf("allocsMinusfrees %i\n", self->allocs - self->frees); 67 | printf("allocatedBytes %i\n", self->allocatedBytes); 68 | printf("maxAllocatedBytes %i\n", self->maxAllocatedBytes); 69 | //printf("allocs %i bytes %i\n", self->allocs, self->allocatedBytes); 70 | } 71 | 72 | static Allocator *_globalAllocator; 73 | 74 | Allocator *globalAllocator(void) 75 | { 76 | if(!_globalAllocator) Allocator_new(); 77 | return _globalAllocator; 78 | } 79 | */ 80 | 81 | // ------------------------------------------------------- 82 | 83 | typedef struct MemoryBlock MemoryBlock; 84 | 85 | struct MemoryBlock 86 | { 87 | size_t size; 88 | size_t allocNum; 89 | char *file; 90 | int line; 91 | MemoryBlock *next; 92 | MemoryBlock *prev; 93 | char padding[40 - (sizeof(size_t) + sizeof(size_t) + sizeof(char *) + sizeof(int) + sizeof(void *) + sizeof(void *))]; 94 | }; 95 | 96 | MemoryBlock *PtrToMemoryBlock(void *ptr) 97 | { 98 | return (MemoryBlock *)(((char *)ptr) - sizeof(MemoryBlock)); 99 | } 100 | 101 | void *MemoryBlockToPtr(MemoryBlock *self) 102 | { 103 | return (void *)(((char *)self) + sizeof(MemoryBlock)); 104 | } 105 | 106 | static MemoryBlock *_baseblock = NULL; 107 | 108 | //inline 109 | MemoryBlock *baseblock(void) 110 | { 111 | if(!_baseblock) _baseblock = calloc(1, sizeof(MemoryBlock)); 112 | return _baseblock; 113 | } 114 | 115 | void MemoryBlock_remove(MemoryBlock *self) 116 | { 117 | if (self->next) self->next->prev = self->prev; 118 | if (self->prev) self->prev->next = self->next; 119 | } 120 | 121 | void MemoryBlock_insertAfter_(MemoryBlock *self, MemoryBlock *other) 122 | { 123 | self->next = other->next; 124 | self->prev = other; 125 | other->next = self; 126 | if (self->next) self->next->prev = self; 127 | } 128 | 129 | MemoryBlock *MemoryBlock_newWithSize_file_line_(size_t size, char *file, int line) 130 | { 131 | MemoryBlock *self = calloc(1, sizeof(MemoryBlock) + size); 132 | self->size = size; 133 | self->allocNum = allocs; 134 | self->file = file; 135 | self->line = line; 136 | MemoryBlock_insertAfter_(self, baseblock()); 137 | 138 | allocs ++; 139 | allocatedBytes += size; 140 | if (allocatedBytes > maxAllocatedBytes) maxAllocatedBytes = allocatedBytes; 141 | return self; 142 | } 143 | 144 | MemoryBlock *MemoryBlock_reallocToSize_(MemoryBlock *self, size_t size) 145 | { 146 | MemoryBlock *prev = self->prev; 147 | MemoryBlock_remove(self); 148 | allocatedBytes -= self->size; 149 | allocatedBytes += size; 150 | reallocs ++; 151 | self = realloc(self, sizeof(MemoryBlock) + size); 152 | self->size = size; 153 | MemoryBlock_insertAfter_(self, prev); 154 | return self; 155 | } 156 | 157 | void MemoryBlock_free(MemoryBlock *self) 158 | { 159 | MemoryBlock_remove(self); 160 | allocatedBytes -= self->size; 161 | frees ++; 162 | free(self); 163 | } 164 | 165 | size_t MemoryBlock_size(MemoryBlock *self) 166 | { 167 | return self->size; 168 | } 169 | 170 | void MemoryBlock_show(MemoryBlock *self) 171 | { 172 | char *file = strrchr(self->file, '/'); 173 | file = file ? file + 1 : self->file; 174 | //printf(" MemoryBlock %p:\n", (void *)self); 175 | //printf("\tsize %i\n", self->size); 176 | //printf("\tfile %s\n", file); 177 | //printf("\tline %i\n", self->line); 178 | printf("\t%i %p %s:%i\t\t%i bytes\n", self->allocNum, MemoryBlockToPtr(self), file, self->line, self->size); 179 | } 180 | 181 | // ---------------------------------------------------------------------------- 182 | 183 | void *io_real_malloc(size_t size, char *file, int line) 184 | { 185 | MemoryBlock *m = MemoryBlock_newWithSize_file_line_(size, file, line); 186 | return MemoryBlockToPtr(m); 187 | } 188 | 189 | void *io_real_calloc(size_t count, size_t size, char *file, int line) 190 | { 191 | return io_real_malloc(count * size, file, line); 192 | } 193 | 194 | void *io_real_realloc(void *ptr, size_t size, char *file, int line) 195 | { 196 | if (ptr) 197 | { 198 | MemoryBlock *m = MemoryBlock_reallocToSize_(PtrToMemoryBlock(ptr), size); 199 | return MemoryBlockToPtr(m); 200 | } 201 | 202 | return io_real_malloc(size, file, line); 203 | } 204 | 205 | void io_free(void *ptr) 206 | { 207 | MemoryBlock_free(PtrToMemoryBlock(ptr)); 208 | } 209 | 210 | // -------------------------------------------------------------------------- 211 | 212 | void io_show_mem(char *s) 213 | { 214 | printf("\n--- %s ---\n", s ? s : ""); 215 | printf("allocs %i\n", allocs); 216 | printf("reallocs %i\n", reallocs); 217 | printf("frees %i\n", frees); 218 | printf("allocsMinusfrees %i\n", allocs - frees); 219 | printf("allocatedBytes %i\n", allocatedBytes); 220 | printf("maxAllocatedBytes %i\n", maxAllocatedBytes); 221 | //printf("allocs %i bytes %i\n", allocs, allocatedBytes); 222 | //printf("\n"); 223 | } 224 | 225 | size_t io_maxAllocatedBytes(void) 226 | { 227 | return maxAllocatedBytes; 228 | } 229 | 230 | void io_resetMaxAllocatedBytes(void) 231 | { 232 | maxAllocatedBytes = allocatedBytes; 233 | } 234 | 235 | size_t io_frees(void) 236 | { 237 | return frees; 238 | } 239 | 240 | size_t io_allocatedBytes(void) 241 | { 242 | return allocatedBytes; 243 | } 244 | 245 | size_t io_allocs(void) 246 | { 247 | return allocs; 248 | } 249 | 250 | void io_showUnfreed(void) 251 | { 252 | MemoryBlock *m = baseblock()->next; 253 | size_t sum = 0; 254 | int n = 0; 255 | 256 | while (m) 257 | { 258 | MemoryBlock_show(m); 259 | sum += m->size; 260 | n ++; 261 | m = m->next; 262 | } 263 | 264 | printf("\n %i bytes in %i blocks\n", (int)sum, n); 265 | } 266 | 267 | #endif 268 | 269 | void *cpalloc(const void *p, size_t size) 270 | { 271 | void *n = io_malloc(size); 272 | if(p) memcpy(n, p, size); 273 | return n; 274 | } 275 | 276 | void *io_freerealloc(void *p, size_t size) 277 | { 278 | return realloc(p, size); 279 | /* 280 | void *n = io_malloc(size); 281 | 282 | if (p != NULL) 283 | { 284 | memcpy(n, p, size); 285 | free(p); 286 | } 287 | 288 | return n; 289 | */ 290 | } 291 | 292 | int io_isBigEndian(void) 293 | { 294 | int i = 0x1; 295 | uint8_t *s = (uint8_t *)(&i); 296 | return s[0]; 297 | } 298 | 299 | uint32_t io_uint32InBigEndian(uint32_t i) 300 | { 301 | uint32_t o; 302 | uint8_t *os = (uint8_t *)&o; 303 | uint8_t *is = (uint8_t *)&i; 304 | if (io_isBigEndian()) return i; 305 | os[0] = is[3]; 306 | os[1] = is[2]; 307 | os[2] = is[1]; 308 | os[3] = is[0]; 309 | return o; 310 | } 311 | 312 | -------------------------------------------------------------------------------- /source/Common.h: -------------------------------------------------------------------------------- 1 | 2 | //metadoc Common copyright Steve Dekorte 2002 3 | //metadoc Common license BSD revised 4 | /*metadoc Common description 5 | This is a header that all other source files should include. 6 | These defines are helpful for doing OS specific checks in the code. 7 | */ 8 | 9 | 10 | #ifndef IOCOMMON_DEFINED 11 | #define IOCOMMON_DEFINED 1 12 | 13 | /*#define LOW_MEMORY_SYSTEM 1*/ 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | #if defined (__SVR4) && defined (__sun) 20 | #include 21 | #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) 22 | #include 23 | #elif !defined(__SYMBIAN32__) && !defined(_MSC_VER) && !defined(__NeXT__) 24 | #include 25 | #else 26 | typedef unsigned char uint8_t; 27 | typedef signed char int8_t; 28 | typedef unsigned short uint16_t; 29 | typedef signed short int16_t; 30 | typedef unsigned long uint32_t; 31 | typedef signed long int32_t; 32 | /* 33 | typedef unsigned long uint64_t; 34 | typedef signed long int64_t; 35 | */ 36 | typedef unsigned long long uint64_t; 37 | typedef long long int64_t; 38 | #endif 39 | 40 | /* Windows stuff */ 41 | 42 | #if defined(WIN32) || defined(__WINS__) || defined(__MINGW32__) || defined(_MSC_VER) 43 | #define inline __inline 44 | #define snprintf _snprintf 45 | #define usleep(x) Sleep(((x)+999)/1000) 46 | 47 | #define HAS_FIBERS 1 48 | 49 | #define ON_WINDOWS 1 50 | 51 | // this also includes windows.h 52 | #include 53 | 54 | // Enable fibers 55 | #ifndef _WIN32_WINNT 56 | #define _WIN32_WINNT 0x0400 57 | #endif 58 | 59 | #if !defined(__MINGW32__) 60 | #if defined(BUILDING_BASEKIT_DLL) || defined(BUILDING_IOVMALL_DLL) 61 | #define BASEKIT_API __declspec(dllexport) 62 | #else 63 | #define BASEKIT_API __declspec(dllimport) 64 | #endif 65 | #else 66 | #define BASEKIT_API 67 | #endif 68 | /* 69 | #ifndef _SYS_STDINT_H_ 70 | #include "PortableStdint.h" 71 | #endif 72 | */ 73 | 74 | #if !defined(__MINGW32__) 75 | /* disable compile warnings which are always treated 76 | as errors in my dev settings */ 77 | 78 | #pragma warning( disable : 4244 ) 79 | /* warning C4244: 'function' : conversion from 'double ' to 'int ', possible loss of data */ 80 | 81 | #pragma warning( disable : 4996 ) 82 | /* warning C4996: 'function' : This function or variable may be unsafe. Consider using 'function_s' instead */ 83 | 84 | #pragma warning( disable : 4018 ) 85 | /* warning C4018: 'operator' : signed/unsigned mismatch */ 86 | 87 | /*#pragma warning( disable : 4090 ) */ 88 | /* warning C4090: 'function' : different 'const' qualifiers */ 89 | 90 | /*#pragma warning( disable : 4024 )*/ 91 | /* warning C4024: different types for formal and actual parameter */ 92 | 93 | /*#pragma warning( disable : 4761 ) */ 94 | /* warning C4761: integral size mismatch in argument; conversion supplied */ 95 | 96 | /*#pragma warning( disable : 4047 ) */ 97 | /* warning C4047: '=' : 'char *' differs in levels of indirection from 'int ' */ 98 | #define ARCHITECTURE_x86 1 99 | #endif 100 | 101 | /* io_malloc, io_realloc, io_free undefined */ 102 | #if !defined(__SYMBIAN32__) 103 | #include 104 | 105 | /* strlen undefined */ 106 | #include 107 | #include /* for calloc */ 108 | #endif 109 | #else 110 | 111 | // Not on windows so define this away 112 | #define BASEKIT_API 113 | 114 | #endif 115 | 116 | /* 117 | [DBCS Enabling] 118 | 119 | DBCS (Short for Double-Byte Character Set), a character set that uses two-byte (16-bit) characters. Some languages, such as Chinese, Japanese and Korean (CJK), have writing schemes with many different characters that cannot be represented with single-byte codes such as ASCII and EBCDIC. 120 | 121 | In CJK world, CES (Character Encoding Scheme) and CCS (Coded Character Set) are actually different concept(one CES may contain multiple CCS). 122 | For example, EUC-JP is a CES which includes CCS of ASCII and JIS X 0208 (optionally JIS X 0201 Kana and JIS X 0212). 123 | 124 | In Japanese (because I am Japanese), 125 | While EUC-JP and UTF-8 Map ASCII unchanged, ShiftJIS not (However ShiftJIS is de facto standard in Japan). For example, {0x95, 0x5c} represents one character. in ASCII, second byte(0x5c) is back slash character. 126 | */ 127 | 128 | /* 129 | check whether double-byte character. supported only ShiftJIS. 130 | if you want to use ShiftJIS characters in string literal, set compiler option -DDBCS_ENABLED=1. 131 | */ 132 | 133 | #if DBCS_ENABLED 134 | #define ismbchar(c) ISSJIS((unsigned char)c) 135 | #define mbcharlen(c) 2 136 | #define ISSJIS(c) ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc)) 137 | #else 138 | #define ismbchar(c) 0 139 | #define mbcharlen(c) 1 140 | #endif /* DBCS_ENABLED */ 141 | 142 | #ifdef __cplusplus 143 | extern "C" { 144 | #endif 145 | 146 | //#define IO_CHECK_ALLOC 147 | 148 | #ifdef IO_CHECK_ALLOC 149 | BASEKIT_API size_t io_memsize(void *ptr); 150 | 151 | #define io_malloc(size) io_real_malloc(size, __FILE__, __LINE__) 152 | BASEKIT_API void *io_real_malloc(size_t size, char *file, int line); 153 | 154 | #define io_calloc(count, size) io_real_calloc(count, size, __FILE__, __LINE__) 155 | BASEKIT_API void *io_real_calloc(size_t count, size_t size, char *file, int line); 156 | 157 | #define io_realloc(ptr, size) io_real_realloc(ptr, size, __FILE__, __LINE__) 158 | BASEKIT_API void *io_real_realloc(void *ptr, size_t newSize, char *file, int line); 159 | 160 | BASEKIT_API void io_free(void *ptr); 161 | BASEKIT_API void io_show_mem(char *s); 162 | BASEKIT_API size_t io_maxAllocatedBytes(void); 163 | BASEKIT_API void io_resetMaxAllocatedBytes(void); 164 | BASEKIT_API size_t io_frees(void); 165 | BASEKIT_API size_t io_allocs(void); 166 | BASEKIT_API size_t io_allocatedBytes(void); 167 | 168 | BASEKIT_API void io_showUnfreed(void); 169 | #else 170 | #define io_memsize 171 | #define io_malloc malloc 172 | #define io_calloc calloc 173 | #define io_realloc io_freerealloc 174 | #define io_free free 175 | #define io_show_mem 176 | 177 | #define io_maxAllocatedBytes() 0 178 | #define io_frees() 0 179 | #define io_allocs() 0 180 | #define io_allocatedBytes() 0 181 | #define io_resetMaxAllocatedBytes() 182 | #endif 183 | 184 | BASEKIT_API void *cpalloc(const void *p, size_t size); 185 | BASEKIT_API void *io_freerealloc(void *p, size_t size); 186 | 187 | int io_isBigEndian(void); 188 | BASEKIT_API uint32_t io_uint32InBigEndian(uint32_t i); 189 | 190 | #ifdef __cplusplus 191 | } 192 | #endif 193 | 194 | #endif 195 | 196 | 197 | 198 | -------------------------------------------------------------------------------- /source/Common_inline.h: -------------------------------------------------------------------------------- 1 | 2 | //metadoc Common copyright Steve Dekorte 2002 3 | //metadoc Common license BSD revised 4 | /*metadoc Common description 5 | You may need to add an entry for your C compiler. 6 | */ 7 | 8 | /* 9 | Trick to get inlining to work with various compilers 10 | Kudos to Daniel A. Koepke 11 | */ 12 | 13 | #undef IO_DECLARE_INLINES 14 | #undef IOINLINE 15 | 16 | /* 17 | #if defined(__cplusplus) 18 | #ifdef IO_IN_C_FILE 19 | #else 20 | #define IO_DECLARE_INLINES 21 | #define IOINLINE extern inline 22 | #endif 23 | #else 24 | */ 25 | 26 | #if defined(__APPLE__) 27 | #include "TargetConditionals.h" 28 | #endif 29 | 30 | #if defined __XCODE__ && (TARGET_ASPEN_SIMULATOR || TARGET_OS_ASPEN) 31 | #define NON_EXTERN_INLINES 32 | #else 33 | #if defined __GNUC__ && __GNUC__ >= 4 34 | //#define NON_EXTERN_INLINES 35 | #endif 36 | #endif 37 | 38 | #ifdef NON_EXTERN_INLINES 39 | 40 | #ifdef IO_IN_C_FILE 41 | // in .c 42 | #define IO_DECLARE_INLINES 43 | #define IOINLINE 44 | #else 45 | // in .h 46 | #define IO_DECLARE_INLINES 47 | #define IOINLINE inline 48 | #endif 49 | 50 | #else 51 | 52 | #ifdef IO_IN_C_FILE 53 | // in .c 54 | #define IO_DECLARE_INLINES 55 | #define IOINLINE inline 56 | #else 57 | // in .h 58 | #define IO_DECLARE_INLINES 59 | #define IOINLINE extern inline 60 | #endif 61 | 62 | #endif 63 | 64 | /* 65 | #endif 66 | */ 67 | -------------------------------------------------------------------------------- /source/Date.c: -------------------------------------------------------------------------------- 1 | 2 | //metadoc Date copyright Steve Dekorte 2002 3 | //metadoc Date license BSD revised 4 | 5 | #define DATE_C 6 | #include "Date.h" 7 | #undef DATE_C 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "PortableStrptime.h" 14 | #include "UArray.h" 15 | 16 | Date *Date_new(void) 17 | { 18 | Date *self = (Date *)io_calloc(1, sizeof(Date)); 19 | Date_now(self); 20 | return self; 21 | } 22 | 23 | void Date_copy_(Date *self, const Date *other) 24 | { 25 | memcpy(self, other, sizeof(Date)); 26 | } 27 | 28 | void Date_free(Date *self) 29 | { 30 | io_free(self); 31 | } 32 | 33 | int Date_compare(const Date *self, const Date *other) 34 | { 35 | double s1 = Date_asSeconds(self); 36 | double s2 = Date_asSeconds(other); 37 | 38 | if (s1 == s2) 39 | { 40 | return 0; 41 | } 42 | 43 | return s1 > s2 ? 1 : -1; 44 | } 45 | 46 | double Date_SecondsFrom1970ToNow(void) 47 | { 48 | double s, us; 49 | struct timeval timeval; 50 | struct timezone timezone; 51 | 52 | gettimeofday(&timeval, &timezone); 53 | s = timeval.tv_sec; 54 | //s -= timezone.tz_minuteswest * 60; 55 | us = timeval.tv_usec; 56 | 57 | return s + (us/1000000.0); /* + (60*60);*/ 58 | } 59 | 60 | void Date_now(Date *self) 61 | { 62 | double s, us; 63 | struct timeval timeval; 64 | struct timezone timezone; 65 | 66 | gettimeofday(&timeval, &timezone); 67 | s = timeval.tv_sec; 68 | s -= timezone.tz_minuteswest * 60; 69 | us = timeval.tv_usec; 70 | 71 | self->tv = timeval; 72 | self->tz = timezone; 73 | } 74 | 75 | double Date_Clock(void) 76 | { 77 | return ((double)clock())/((double)CLOCKS_PER_SEC); 78 | } 79 | 80 | // zone -------------------------------------------------------- 81 | 82 | void Date_setToLocalTimeZone(Date *self) 83 | { 84 | struct timeval timeval; 85 | gettimeofday(&timeval, &(self->tz)); 86 | } 87 | 88 | struct timezone Date_timeZone(const Date *self) 89 | { 90 | return self->tz; 91 | } 92 | 93 | void Date_setTimeZone_(Date *self, struct timezone tz) 94 | { 95 | self->tz = tz; 96 | } 97 | 98 | void Date_convertToTimeZone_(Date *self, struct timezone tz) 99 | { 100 | double s = Date_asSeconds(self) + 101 | ((self->tz.tz_minuteswest - tz.tz_minuteswest) * 60); 102 | Date_fromSeconds_(self, s); 103 | Date_setTimeZone_(self, tz); 104 | } 105 | 106 | // time -------------------------------------------------------- 107 | 108 | void Date_fromLocalTime_(Date *self, struct tm *t) 109 | { 110 | Date_fromTime_(self, mktime(t)); 111 | } 112 | 113 | void Date_fromTime_(Date *self, time_t t) 114 | { 115 | Date_fromSeconds_(self, (double)t); 116 | } 117 | 118 | time_t Date_asTime(const Date *self) 119 | { 120 | return (time_t)self->tv.tv_sec; 121 | } 122 | 123 | // sconds -------------------------------------------------------- 124 | 125 | double Date_asSeconds(const Date *self) 126 | { 127 | return ((double)self->tv.tv_sec) + (((double)self->tv.tv_usec) / 1000000.0); 128 | } 129 | 130 | void Date_fromSeconds_(Date *self, double s) 131 | { 132 | long secs = s; 133 | self->tv.tv_sec = secs; 134 | self->tv.tv_usec = (s - secs)*1000000; 135 | } 136 | 137 | void Date_addSeconds_(Date *self, double s) 138 | { 139 | long secs = s; 140 | self->tv.tv_sec += secs; 141 | self->tv.tv_usec += (s - secs)*1000000; 142 | } 143 | 144 | double Date_secondsSince_(const Date *self, const Date *other) 145 | { 146 | long s = self->tv.tv_sec - other->tv.tv_sec; 147 | long us = self->tv.tv_usec - other->tv.tv_usec; 148 | return ((double)s) + (((double)us)/1000000.0); 149 | } 150 | 151 | // components -------------------------------------------------------- 152 | 153 | long Date_year(const Date *self) 154 | { 155 | time_t t = self->tv.tv_sec; 156 | struct tm *tm = localtime(&t); 157 | return tm->tm_year + 1900; 158 | } 159 | 160 | void Date_setYear_(Date *self, long v) 161 | { 162 | time_t t = self->tv.tv_sec; 163 | struct tm *tm = localtime(&t); 164 | tm->tm_year = v - 1900; 165 | self->tv.tv_sec = mktime(tm); 166 | } 167 | 168 | int Date_month(const Date *self) 169 | { 170 | time_t t = self->tv.tv_sec; 171 | struct tm *tm = localtime(&t); 172 | return tm->tm_mon; 173 | } 174 | 175 | void Date_setMonth_(Date *self, int v) 176 | { 177 | time_t t = self->tv.tv_sec; 178 | struct tm *tm = localtime(&t); 179 | tm->tm_mon = v; 180 | self->tv.tv_sec = mktime(tm); 181 | } 182 | 183 | int Date_day(const Date *self) 184 | { 185 | time_t t = self->tv.tv_sec; 186 | struct tm *tm = localtime(&t); 187 | return tm->tm_mday; 188 | } 189 | 190 | void Date_setDay_(Date *self, int v) 191 | { 192 | time_t t = self->tv.tv_sec; 193 | struct tm *tm = localtime(&t); 194 | tm->tm_mday = v; 195 | self->tv.tv_sec = mktime(tm); 196 | } 197 | 198 | int Date_hour(const Date *self) 199 | { 200 | time_t t = self->tv.tv_sec; 201 | struct tm *tm = localtime(&t); 202 | return tm->tm_hour; 203 | } 204 | 205 | void Date_setHour_(Date *self, int v) 206 | { 207 | time_t t = self->tv.tv_sec; 208 | struct tm *tm = localtime(&t); 209 | tm->tm_hour = v; 210 | self->tv.tv_sec = mktime(tm); 211 | } 212 | 213 | int Date_minute(const Date *self) 214 | { 215 | time_t t = self->tv.tv_sec; 216 | struct tm *tm = localtime(&t); 217 | return tm->tm_min; 218 | } 219 | 220 | void Date_setMinute_(Date *self, int v) 221 | { 222 | time_t t = self->tv.tv_sec; 223 | struct tm *tm = localtime(&t); 224 | tm->tm_min = v; 225 | self->tv.tv_sec = mktime(tm); 226 | } 227 | 228 | double Date_second(const Date *self) 229 | { 230 | time_t t = self->tv.tv_sec; 231 | struct tm *tm = localtime(&t); 232 | return ((double)tm->tm_sec) + ((double)self->tv.tv_usec)/1000000.0; 233 | } 234 | 235 | void Date_setSecond_(Date *self, double v) 236 | { 237 | time_t t = self->tv.tv_sec; 238 | struct tm *tm = localtime(&t); 239 | tm->tm_sec = v; 240 | self->tv.tv_sec = mktime(tm); 241 | self->tv.tv_usec = (v - ((long)v))*1000000; 242 | } 243 | 244 | UArray *Date_asSerialization(Date *self) 245 | { 246 | int32_t *data = malloc(4 * sizeof(int32_t)); 247 | 248 | data[0] = self->tv.tv_sec; 249 | data[1] = self->tv.tv_usec; 250 | data[2] = self->tz.tz_minuteswest; 251 | data[3] = self->tz.tz_dsttime; 252 | 253 | return UArray_newWithData_type_encoding_size_copy_(data, CTYPE_int32_t, CENCODING_NUMBER, 4, 0); 254 | } 255 | 256 | Date *Date_fromSerialization(Date *self, UArray *serialization) 257 | { 258 | self->tv.tv_sec = UArray_longAt_(serialization, 0); 259 | self->tv.tv_usec = UArray_longAt_(serialization, 1); 260 | self->tz.tz_minuteswest = UArray_longAt_(serialization, 2); 261 | self->tz.tz_dsttime = UArray_longAt_(serialization, 3); 262 | 263 | return self; 264 | } 265 | 266 | unsigned char Date_isDaylightSavingsTime(const Date *self) 267 | { 268 | time_t t = self->tv.tv_sec; 269 | struct tm *tm = localtime(&t); 270 | return (unsigned char)tm->tm_isdst; 271 | } 272 | 273 | int Date_isLeapYear(const Date *self) 274 | { 275 | int year = Date_year(self); 276 | 277 | if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) 278 | { 279 | return 1; 280 | } 281 | else 282 | { 283 | return 0; 284 | } 285 | } 286 | 287 | // format -------------------------------------------------------- 288 | 289 | static struct tm EmptyTM(void) 290 | { 291 | time_t tmp = 0; 292 | struct tm *tt = localtime(&tmp); 293 | struct tm t; 294 | 295 | memcpy(&t, tt, sizeof(struct tm)); 296 | t.tm_sec = 0; 297 | t.tm_min = 0; 298 | t.tm_hour = 0; 299 | t.tm_mday = 0; 300 | t.tm_mon = 0; 301 | t.tm_year = 0; 302 | t.tm_wday = 0; 303 | t.tm_yday = 0; 304 | return t; 305 | } 306 | 307 | void Date_fromString_format_(Date *self, const char *s, const char *format) 308 | { 309 | struct tm tm = EmptyTM(); 310 | io_strptime((char *)s, (char *)format, &tm); 311 | /* 312 | printf("year = %i\n", t.tm_year); 313 | printf("month = %i\n", t.tm_mon); 314 | printf("day = %i\n", t.tm_mday); 315 | printf("hour = %i\n", t.tm_hour); 316 | printf("min = %i\n", t.tm_min); 317 | printf("sec = %i\n", t.tm_sec); 318 | */ 319 | Date_fromSeconds_(self, mktime(&tm)); 320 | } 321 | 322 | // durations -------------------------------------------------------- 323 | 324 | Duration *Date_newDurationBySubtractingDate_(const Date *self, const Date *other) 325 | { 326 | double d = Date_secondsSince_(self, other); 327 | return Duration_newWithSeconds_(d); 328 | } 329 | 330 | void Date_addDuration_(Date *self, const Duration *d) 331 | { 332 | Date_addSeconds_(self, Duration_asSeconds(d)); 333 | } 334 | 335 | void Date_subtractDuration_(Date *self, const Duration *d) 336 | { 337 | Date_addSeconds_(self, -Duration_asSeconds(d)); 338 | } 339 | 340 | // ----------------------------------------------------------- 341 | 342 | double Date_secondsSinceNow(const Date *self) 343 | { 344 | Date *now = Date_new(); 345 | double s = Date_secondsSince_(now, self); 346 | Date_free(now); 347 | return s; 348 | } 349 | 350 | // format -------------------------------------------------------- 351 | 352 | UArray *Date_asString(const Date *self, const char *format) 353 | { 354 | UArray *u = UArray_new(); 355 | time_t t = self->tv.tv_sec; 356 | struct tm *tm = localtime(&t); 357 | 358 | // what about unicode formats? 359 | UArray_setSize_(u, 1024 + strlen(format)); 360 | strftime((char *)UArray_bytes(u), 1024, format, tm); 361 | UArray_setSize_(u, strlen((char *)UArray_bytes(u))); 362 | 363 | return u; 364 | } 365 | -------------------------------------------------------------------------------- /source/Date.h: -------------------------------------------------------------------------------- 1 | //metadoc Date copyright Steve Dekorte 2002 2 | //metadoc Date license BSD revised 3 | 4 | #include "Base.h" 5 | 6 | #ifndef DATE_DEFINED 7 | #define DATE_DEFINED 1 8 | 9 | #include "Common.h" 10 | #include "Duration.h" 11 | #include "PortableGettimeofday.h" 12 | #include 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | typedef struct 19 | { 20 | struct timeval tv; 21 | struct timezone tz; 22 | } Date; 23 | 24 | BASEKIT_API double Date_SecondsFrom1970ToNow(void); 25 | 26 | BASEKIT_API Date *Date_new(void); 27 | BASEKIT_API void Date_copy_(Date *self, const Date *other); 28 | BASEKIT_API void Date_free(Date *self); 29 | BASEKIT_API int Date_compare(const Date *self, const Date *other); 30 | 31 | BASEKIT_API void Date_now(Date *self); 32 | BASEKIT_API void Date_setToLocalTimeZone(Date *self); 33 | BASEKIT_API double Date_Clock(void); 34 | 35 | BASEKIT_API void Date_fromLocalTime_(Date *self, struct tm *t); 36 | BASEKIT_API void Date_fromTime_(Date *self, time_t t); 37 | BASEKIT_API time_t Date_asTime(const Date *self); 38 | 39 | // zone 40 | 41 | BASEKIT_API void Date_setToLocalTimeZone(Date *self); 42 | struct timezone Date_timeZone(const Date *self); 43 | BASEKIT_API void Date_setTimeZone_(Date *self, struct timezone tz); 44 | BASEKIT_API void Date_convertToTimeZone_(Date *self, struct timezone tz); 45 | 46 | // components 47 | 48 | BASEKIT_API void Date_setYear_(Date *self, long y); 49 | BASEKIT_API long Date_year(const Date *self); 50 | 51 | BASEKIT_API void Date_setMonth_(Date *self, int m); 52 | BASEKIT_API int Date_month(const Date *self); 53 | 54 | BASEKIT_API void Date_setDay_(Date *self, int d); 55 | BASEKIT_API int Date_day(const Date *self); 56 | 57 | BASEKIT_API void Date_setHour_(Date *self, int h); 58 | BASEKIT_API int Date_hour(const Date *self); 59 | 60 | BASEKIT_API void Date_setMinute_(Date *self, int m); 61 | BASEKIT_API int Date_minute(const Date *self); 62 | 63 | BASEKIT_API void Date_setSecond_(Date *self, double s); 64 | BASEKIT_API double Date_second(const Date *self); 65 | 66 | BASEKIT_API UArray *Date_asSerialization(Date *self); 67 | BASEKIT_API Date *Date_fromSerialization(Date *self, UArray *serialization); 68 | 69 | BASEKIT_API unsigned char Date_isDaylightSavingsTime(const Date *self); 70 | BASEKIT_API int Date_isLeapYear(const Date *self); 71 | 72 | // seconds 73 | 74 | BASEKIT_API double Date_asSeconds(const Date *self); 75 | BASEKIT_API void Date_fromSeconds_(Date *self, double s); 76 | 77 | BASEKIT_API void Date_addSeconds_(Date *self, double s); 78 | BASEKIT_API double Date_secondsSince_(const Date *self, const Date *other); 79 | 80 | // format 81 | 82 | BASEKIT_API void Date_fromString_format_(Date *self, const char *s, const char *format); 83 | 84 | // durations 85 | 86 | BASEKIT_API Duration *Date_newDurationBySubtractingDate_(const Date *self, const Date *other); 87 | BASEKIT_API void Date_addDuration_(Date *self, const Duration *d); 88 | BASEKIT_API void Date_subtractDuration_(Date *self, const Duration *d); 89 | 90 | BASEKIT_API double Date_secondsSinceNow(const Date *self); 91 | 92 | BASEKIT_API UArray *Date_asString(const Date *self, const char *format); 93 | 94 | #ifdef __cplusplus 95 | } 96 | #endif 97 | #endif 98 | -------------------------------------------------------------------------------- /source/Duration.c: -------------------------------------------------------------------------------- 1 | //metadoc Duration copyright Steve Dekorte 2002 2 | //metadoc Duration license BSD revised 3 | 4 | #define DURATION_C 5 | #include "Duration.h" 6 | #undef DURATION_C 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | typedef struct 13 | { 14 | double years; 15 | double days; 16 | double hours; 17 | double minutes; 18 | double seconds; 19 | } DurationComponents; 20 | 21 | Duration *Duration_new(void) 22 | { 23 | Duration *self = (Duration *)io_calloc(1, sizeof(Duration)); 24 | return self; 25 | } 26 | 27 | Duration *Duration_newWithSeconds_(double s) 28 | { 29 | Duration *self = Duration_new(); 30 | self->seconds = s; 31 | return self; 32 | } 33 | 34 | void Duration_copy_(Duration *self, const Duration *other) 35 | { 36 | memcpy(self, other, sizeof(Duration)); 37 | } 38 | 39 | void Duration_free(Duration *self) 40 | { 41 | io_free(self); 42 | } 43 | 44 | int Duration_compare(const Duration *self, const Duration *other) 45 | { 46 | if (self->seconds == other->seconds) 47 | { 48 | return 0; 49 | } 50 | 51 | return self->seconds > other->seconds ? 1 : -1; 52 | } 53 | 54 | // components -------------------------------------------------------- 55 | 56 | #define SECONDS_IN_YEAR (60 * 60 * 24 * 365) 57 | #define SECONDS_IN_DAY (60 * 60 * 24) 58 | #define SECONDS_IN_HOUR (60 * 60) 59 | #define SECONDS_IN_MINUTE (60) 60 | 61 | DurationComponents Duration_asComponents(const Duration *self) 62 | { 63 | DurationComponents c; 64 | double t = self->seconds; 65 | c.years = (int)(t / SECONDS_IN_YEAR); t -= (int)(c.years * SECONDS_IN_YEAR); 66 | c.days = (int)(t / SECONDS_IN_DAY); t -= (int)(c.days * SECONDS_IN_DAY); 67 | c.hours = (int)(t / SECONDS_IN_HOUR); t -= (int)(c.hours * SECONDS_IN_HOUR); 68 | c.minutes = (int)(t / SECONDS_IN_MINUTE); t -= (int)(c.minutes * SECONDS_IN_MINUTE); 69 | c.seconds = (t); 70 | return c; 71 | } 72 | 73 | void Duration_fromComponents_(Duration *self, DurationComponents c) 74 | { 75 | double t = c.years * SECONDS_IN_YEAR; 76 | t += c.days * SECONDS_IN_DAY; 77 | t += c.hours * SECONDS_IN_HOUR; 78 | t += c.minutes * SECONDS_IN_MINUTE; 79 | t += c.seconds; 80 | self->seconds = t; 81 | } 82 | 83 | // years -------------------------------------------------------- 84 | 85 | int Duration_years(const Duration *self) 86 | { 87 | return (int)Duration_asComponents(self).years; 88 | } 89 | 90 | void Duration_setYears_(Duration *self, double y) 91 | { 92 | DurationComponents c = Duration_asComponents(self); 93 | c.years = y; 94 | Duration_fromComponents_(self, c); 95 | } 96 | 97 | // days -------------------------------------------------------- 98 | 99 | int Duration_days(const Duration *self) 100 | { 101 | return (int)Duration_asComponents(self).days; 102 | } 103 | 104 | void Duration_setDays_(Duration *self, double d) 105 | { 106 | DurationComponents c = Duration_asComponents(self); 107 | c.days = d; 108 | Duration_fromComponents_(self, c); 109 | } 110 | 111 | // hours -------------------------------------------------------- 112 | 113 | int Duration_hours(const Duration *self) 114 | { 115 | return (int)Duration_asComponents(self).hours; 116 | } 117 | 118 | void Duration_setHours_(Duration *self, double m) 119 | { 120 | DurationComponents c = Duration_asComponents(self); 121 | c.hours = m; 122 | Duration_fromComponents_(self, c); 123 | } 124 | 125 | // minutes -------------------------------------------------------- 126 | 127 | int Duration_minutes(const Duration *self) 128 | { 129 | return (int)Duration_asComponents(self).minutes; 130 | } 131 | 132 | void Duration_setMinutes_(Duration *self, double m) 133 | { 134 | DurationComponents c = Duration_asComponents(self); 135 | c.minutes = m; 136 | Duration_fromComponents_(self, c); 137 | } 138 | 139 | // seconds -------------------------------------------------------- 140 | 141 | double Duration_seconds(const Duration *self) 142 | { 143 | return Duration_asComponents(self).seconds; 144 | } 145 | 146 | void Duration_setSeconds_(Duration *self, double s) 147 | { 148 | DurationComponents c = Duration_asComponents(self); 149 | c.seconds = s; 150 | Duration_fromComponents_(self, c); 151 | } 152 | 153 | // total seconds -------------------------------------------------------- 154 | 155 | double Duration_asSeconds(const Duration *self) 156 | { 157 | return self->seconds; 158 | } 159 | 160 | void Duration_fromSeconds_(Duration *self, double s) 161 | { 162 | self->seconds = s; 163 | } 164 | 165 | // strings -------------------------------------------------------- 166 | 167 | UArray *Duration_asUArrayWithFormat_(const Duration *self, const char *format) 168 | { 169 | DurationComponents c = Duration_asComponents(self); 170 | char s[128]; 171 | UArray *ba = UArray_newWithCString_(format?format:"%Y years %d days %H:%M:%S"); 172 | 173 | snprintf(s, 128, "%i", (int)c.years); 174 | UArray_replaceCString_withCString_(ba, "%Y", s); 175 | 176 | snprintf(s, 128, "%04i", (int)c.years); 177 | UArray_replaceCString_withCString_(ba, "%y", s); 178 | 179 | snprintf(s, 128, "%02i", (int)c.days); 180 | UArray_replaceCString_withCString_(ba, "%d", s); 181 | 182 | snprintf(s, 128, "%02i", (int)c.hours); 183 | UArray_replaceCString_withCString_(ba, "%H", s); 184 | 185 | snprintf(s, 128, "%02i", (int)c.minutes); 186 | UArray_replaceCString_withCString_(ba, "%M", s); 187 | 188 | snprintf(s, 128, "%02f", c.seconds); 189 | UArray_replaceCString_withCString_(ba, "%S", s); 190 | 191 | return ba; 192 | } 193 | 194 | void Duration_print(const Duration *self) 195 | { 196 | UArray *ba = Duration_asUArrayWithFormat_(self, NULL); 197 | UArray_print(ba); 198 | UArray_free(ba); 199 | } 200 | 201 | // math -------------------------------------------------------- 202 | 203 | void Duration_add_(Duration *self, const Duration *other) 204 | { 205 | self->seconds += other->seconds; 206 | } 207 | 208 | void Duration_subtract_(Duration *self, const Duration *other) 209 | { 210 | self->seconds -= other->seconds; 211 | } 212 | 213 | -------------------------------------------------------------------------------- /source/Duration.h: -------------------------------------------------------------------------------- 1 | //metadoc Duration copyright Steve Dekorte 2002 2 | //metadoc Duration license BSD revised 3 | 4 | #ifndef DURATION_DEFINED 5 | #define DURATION_DEFINED 1 6 | 7 | #include "Common.h" 8 | #include "UArray.h" 9 | #include "PortableGettimeofday.h" 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | typedef struct 16 | { 17 | double seconds; 18 | } Duration; 19 | 20 | BASEKIT_API Duration *Duration_new(void); 21 | BASEKIT_API Duration *Duration_newWithSeconds_(double s); 22 | BASEKIT_API Duration *Duration_clone(const Duration *self); 23 | BASEKIT_API void Duration_copy_(Duration *self, const Duration *other); 24 | 25 | BASEKIT_API void Duration_free(Duration *self); 26 | BASEKIT_API int Duration_compare(const Duration *self, const Duration *other); 27 | 28 | // components 29 | 30 | BASEKIT_API int Duration_years(const Duration *self); 31 | BASEKIT_API void Duration_setYears_(Duration *self, double y); 32 | 33 | BASEKIT_API int Duration_days(const Duration *self); 34 | BASEKIT_API void Duration_setDays_(Duration *self, double d); 35 | 36 | BASEKIT_API int Duration_hours(const Duration *self); 37 | BASEKIT_API void Duration_setHours_(Duration *self, double m); 38 | 39 | BASEKIT_API int Duration_minutes(const Duration *self); 40 | BASEKIT_API void Duration_setMinutes_(Duration *self, double m); 41 | 42 | BASEKIT_API double Duration_seconds(const Duration *self); 43 | BASEKIT_API void Duration_setSeconds_(Duration *self, double s); 44 | 45 | // total seconds 46 | 47 | BASEKIT_API double Duration_asSeconds(const Duration *self); 48 | BASEKIT_API void Duration_fromSeconds_(Duration *self, double s); 49 | 50 | // strings 51 | 52 | BASEKIT_API UArray *Duration_asUArrayWithFormat_(const Duration *self, const char *format); 53 | BASEKIT_API void Duration_print(const Duration *self); 54 | 55 | // math 56 | 57 | BASEKIT_API void Duration_add_(Duration *self, const Duration *other); 58 | BASEKIT_API void Duration_subtract_(Duration *self, const Duration *other); 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | #endif 64 | -------------------------------------------------------------------------------- /source/DynLib.c: -------------------------------------------------------------------------------- 1 | /* 2 | //metadoc DynLib license BSD revised 3 | /*metadoc DynLib history 4 | based on DllHandle.c, contributed by Daniel A. Koepke 5 | Reorg, Steve Dekorte, 2003-08-30 6 | Window fix, Chuck Adams, 2004-02-06 7 | */ 8 | 9 | #include "Base.h" 10 | #include "DynLib.h" 11 | #include "PortableStrlcpy.h" 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #if defined(__WIN32__) || defined(WIN32) || defined(_WIN32) || defined(_MSC_VER) 18 | #include 19 | 20 | #define RTLD_NOW 0 /* don't support link flags */ 21 | #define RTLD_GLOBAL 0 22 | 23 | static void *dlopen(const char *path, int mode) 24 | { 25 | void *result; 26 | result = (void *)LoadLibraryEx(path, NULL, 0); 27 | if (result) 28 | SetLastError(ERROR_SUCCESS); 29 | 30 | return result; 31 | } 32 | 33 | static int dlclose(void *handle) 34 | { 35 | return FreeLibrary((HANDLE)handle); 36 | } 37 | 38 | static const char *dlerror(void) 39 | { 40 | // XXX this will leak the error string 41 | 42 | LPSTR buf; 43 | DWORD err; 44 | err = GetLastError(); 45 | if (err == ERROR_SUCCESS) 46 | return (char*)0; 47 | 48 | FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER 49 | | FORMAT_MESSAGE_IGNORE_INSERTS 50 | | FORMAT_MESSAGE_FROM_SYSTEM, 51 | NULL, err, 52 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 53 | (LPSTR)&buf, 0, NULL); 54 | return buf; 55 | } 56 | 57 | static void *dlsym(void *handle, const char *symbol) 58 | { 59 | return (void*)GetProcAddress((HANDLE)handle, symbol); 60 | } 61 | 62 | 63 | #else 64 | #include 65 | #endif 66 | 67 | DynLib *DynLib_new(void) 68 | { 69 | DynLib *self = (DynLib *)io_calloc(1, sizeof(DynLib)); 70 | DynLib_setPath_(self, ""); 71 | return self; 72 | } 73 | 74 | void DynLib_free(DynLib *self) 75 | { 76 | //DynLib_close(self); 77 | if (self->path) io_free(self->path); 78 | if (self->initFuncName) io_free(self->initFuncName); 79 | if (self->freeFuncName) io_free(self->freeFuncName); 80 | if (self->error) io_free(self->error); 81 | io_free(self); 82 | } 83 | 84 | void DynLib_setPath_(DynLib *self, const char *path) 85 | { 86 | size_t len = strlen(path); 87 | char *ptr = (char*)io_realloc(self->path, len + 1); 88 | PortableStrlcpy(ptr, path, len + 1); 89 | self->path = ptr; 90 | } 91 | 92 | char *DynLib_path(DynLib *self) 93 | { 94 | return self->path; 95 | } 96 | 97 | void DynLib_setInitFuncName_(DynLib *self, const char *name) 98 | { 99 | size_t len = strlen(name); 100 | char* ptr = (char*)io_realloc(self->initFuncName, len + 1); 101 | PortableStrlcpy(ptr, name, len + 1); 102 | self->initFuncName = ptr; 103 | } 104 | 105 | char *DynLib_initFuncName(DynLib *self) 106 | { 107 | return self->initFuncName; 108 | } 109 | 110 | void DynLib_setInitArg_(DynLib *self, void *arg) 111 | { 112 | self->initArg = arg; 113 | } 114 | 115 | void DynLib_setFreeFuncName_(DynLib *self, const char *name) 116 | { 117 | size_t len = strlen(name); 118 | char* ptr = (char*)io_realloc(self->freeFuncName, len + 1); 119 | PortableStrlcpy(ptr, name, len + 1); 120 | self->freeFuncName = ptr; 121 | } 122 | 123 | char *DynLib_freeFuncName(DynLib *self) 124 | { 125 | return self->freeFuncName; 126 | } 127 | 128 | void DynLib_setFreeArg_(DynLib *self, void *arg) 129 | { 130 | self->freeArg = arg; 131 | } 132 | 133 | void DynLib_setError_(DynLib *self,const char *error) 134 | { 135 | if (error) 136 | { 137 | self->error = strcpy((char *)io_realloc(self->error, strlen(error)+1), error); 138 | } 139 | else 140 | { 141 | if (self->error) io_free(self->error); 142 | self->error = NULL; 143 | } 144 | } 145 | 146 | char *DynLib_error(DynLib *self) 147 | { 148 | return self->error; 149 | } 150 | 151 | void DynLib_updateError(DynLib *self) 152 | { 153 | DynLib_setError_(self, dlerror()); 154 | } 155 | 156 | unsigned char DynLib_hasError(DynLib *self) 157 | { 158 | return self->error != NULL; 159 | } 160 | 161 | void DynLib_open(DynLib *self) 162 | { 163 | self->handle = dlopen(self->path, RTLD_NOW | RTLD_GLOBAL); /* RTLD_LAZY); */ 164 | //self->handle = dlopen(self->path, RTLD_NOW | RTLD_LAZY); 165 | DynLib_updateError(self); 166 | 167 | if (DynLib_hasError(self)) 168 | { 169 | return; 170 | } 171 | 172 | if (self->initFuncName) 173 | { 174 | void *f = DynLib_pointerForSymbolName_(self, self->initFuncName); 175 | 176 | if (!f) 177 | { 178 | DynLib_setError_(self, "init function not found"); 179 | return; 180 | } 181 | 182 | if (self->initArg) 183 | { 184 | //printf("DynLib: opening with 1 arg %p\n", self->initArg); 185 | (*(DynLibOneArgFunction *)f)(self->initArg); 186 | } 187 | else 188 | { 189 | (*(DynLibNoArgFunction *)f)(); 190 | } 191 | } 192 | } 193 | 194 | unsigned char DynLib_isOpen(DynLib *self) 195 | { 196 | return self->handle != NULL; 197 | } 198 | 199 | void DynLib_close(DynLib *self) 200 | { 201 | if (self->freeFuncName) 202 | { 203 | void *f = DynLib_pointerForSymbolName_(self, self->freeFuncName); 204 | 205 | if (!f) 206 | { 207 | DynLib_setError_(self, "io_free function not found"); 208 | return; 209 | } 210 | 211 | if (self->freeArg) 212 | { 213 | (*(DynLibOneArgFunction *)f)(self->freeArg); 214 | } 215 | else 216 | { 217 | (*(DynLibNoArgFunction *)f)(); 218 | } 219 | } 220 | 221 | if (self->handle) 222 | { 223 | dlclose(self->handle); 224 | } 225 | 226 | self->handle = NULL; 227 | } 228 | 229 | void *DynLib_pointerForSymbolName_(DynLib *self, const char *symbolName) 230 | { 231 | DynLib_setError_(self, dlerror()); 232 | return dlsym(self->handle, symbolName); 233 | } 234 | 235 | -------------------------------------------------------------------------------- /source/DynLib.h: -------------------------------------------------------------------------------- 1 | /* based on DynLib.c contributed by Daniel A. Koepke 2 | * Reorg, Steve Dekorte, 2003-08-30 3 | * See _BSDLicense.txt 4 | */ 5 | 6 | #ifndef DYNLIB_DEFINED 7 | #define DYNLIB_DEFINED 1 8 | 9 | #include "Common.h" 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | typedef void DynLibNoArgFunction(void); 16 | typedef void DynLibOneArgFunction(void *arg); 17 | 18 | typedef struct 19 | { 20 | char *path; 21 | char *initFuncName; 22 | void *initArg; 23 | char *freeFuncName; 24 | void *freeArg; 25 | char *error; 26 | void *handle; 27 | int refCount; 28 | } DynLib; 29 | 30 | BASEKIT_API DynLib *DynLib_new(void); 31 | BASEKIT_API void DynLib_free(DynLib *self); 32 | 33 | BASEKIT_API void DynLib_setPath_(DynLib *self, const char *path); 34 | BASEKIT_API char *DynLib_path(DynLib *self); 35 | 36 | BASEKIT_API void DynLib_setInitFuncName_(DynLib *self, const char *name); 37 | BASEKIT_API char *DynLib_initFuncName(DynLib *self); 38 | BASEKIT_API void DynLib_setInitArg_(DynLib *self, void *arg); 39 | 40 | BASEKIT_API void DynLib_setFreeFuncName_(DynLib *self, const char *name); 41 | BASEKIT_API char *DynLib_freeFuncName(DynLib *self); 42 | BASEKIT_API void DynLib_setFreeArg_(DynLib *self, void *arg); 43 | 44 | BASEKIT_API void DynLib_setError_(DynLib *self, const char *path); 45 | BASEKIT_API char *DynLib_error(DynLib *self); 46 | 47 | BASEKIT_API void DynLib_open(DynLib *self); 48 | BASEKIT_API unsigned char DynLib_isOpen(DynLib *self); 49 | BASEKIT_API void DynLib_close(DynLib *self); 50 | BASEKIT_API void *DynLib_pointerForSymbolName_(DynLib *self, const char *symbolName); 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | #endif 56 | -------------------------------------------------------------------------------- /source/Hash_fnv.c: -------------------------------------------------------------------------------- 1 | /* 2 | * hash_32 - 32 bit Fowler/Noll/Vo hash code 3 | * 4 | * @(#) $Revision: 1.8 $ 5 | * @(#) $Id: hash_32.c,v 1.8 2003/10/03 20:38:13 chongo Exp $ 6 | * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_32.c,v $ 7 | * 8 | *** 9 | * 10 | * Fowler/Noll/Vo hash 11 | * 12 | * The basis of this hash algorithm was taken from an idea sent 13 | * as reviewer comments to the IEEE POSIX P1003.2 committee by: 14 | * 15 | * Phong Vo (http://www.research.att.com/info/kpv/) 16 | * Glenn Fowler (http://www.research.att.com/~gsf/) 17 | * 18 | * In a subsequent ballot round: 19 | * 20 | * Landon Curt Noll (http://www.isthe.com/chongo/) 21 | * 22 | * improved on their algorithm. Some people tried this hash 23 | * and found that it worked rather well. In an EMail message 24 | * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. 25 | * 26 | * FNV hashes are designed to be fast while maintaining a low 27 | * collision rate. The FNV speed allows one to quickly hash lots 28 | * of data while maintaining a reasonable collision rate. See: 29 | * 30 | * http://www.isthe.com/chongo/tech/comp/fnv/index.html 31 | * 32 | * for more details as well as other forms of the FNV hash. 33 | *** 34 | * 35 | * NOTE: The FNV-0 historic hash is not recommended. One should use 36 | * the FNV-1 hash instead. 37 | * 38 | * To use the 32 bit FNV-0 historic hash, pass FNV0_32_INIT as the 39 | * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). 40 | * 41 | * To use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the 42 | * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). 43 | * 44 | *** 45 | * 46 | * Please do not copyright this code. This code is in the public domain. 47 | * 48 | * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 49 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 50 | * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 51 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 52 | * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 53 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 54 | * PERFORMANCE OF THIS SOFTWARE. 55 | * 56 | * By: 57 | * chongo /\oo/\ 58 | * http://www.isthe.com/chongo/ 59 | * 60 | * Share and Enjoy! :-) 61 | */ 62 | 63 | #include 64 | #include "Hash_fnv.h" 65 | 66 | /* 67 | * 32 bit magic FNV-0 and FNV-1 prime 68 | */ 69 | #define FNV_32_PRIME ((Fnv32_t)0x01000193) 70 | 71 | 72 | /* 73 | * fnv_32_buf - perform a 32 bit Fowler/Noll/Vo hash on a buffer 74 | * 75 | * input: 76 | * buf - start of buffer to hash 77 | * len - length of buffer in octets 78 | * hval - previous hash value or 0 if first call 79 | * 80 | * returns: 81 | * 32 bit hash as a static hash type 82 | * 83 | * NOTE: To use the 32 bit FNV-0 historic hash, use FNV0_32_INIT as the hval 84 | * argument on the first call to either fnv_32_buf() or fnv_32_str(). 85 | * 86 | * NOTE: To use the recommended 32 bit FNV-1 hash, use FNV1_32_INIT as the hval 87 | * argument on the first call to either fnv_32_buf() or fnv_32_str(). 88 | */ 89 | Fnv32_t 90 | fnv_32_buf(void *buf, size_t len, Fnv32_t hval) 91 | { 92 | unsigned char *bp = (unsigned char *)buf; /* start of buffer */ 93 | unsigned char *be = bp + len; /* beyond end of buffer */ 94 | 95 | /* 96 | * FNV-1 hash each octet in the buffer 97 | */ 98 | while (bp < be) { 99 | 100 | /* multiply by the 32 bit FNV magic prime mod 2^32 */ 101 | #if defined(NO_FNV_GCC_OPTIMIZATION) 102 | hval *= FNV_32_PRIME; 103 | #else 104 | hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); 105 | #endif 106 | 107 | /* xor the bottom with the current octet */ 108 | hval ^= (Fnv32_t)*bp++; 109 | } 110 | 111 | /* return our new hash value */ 112 | return hval; 113 | } 114 | 115 | 116 | /* 117 | * fnv_32_str - perform a 32 bit Fowler/Noll/Vo hash on a string 118 | * 119 | * input: 120 | * str - string to hash 121 | * hval - previous hash value or 0 if first call 122 | * 123 | * returns: 124 | * 32 bit hash as a static hash type 125 | * 126 | * NOTE: To use the 32 bit FNV-0 historic hash, use FNV0_32_INIT as the hval 127 | * argument on the first call to either fnv_32_buf() or fnv_32_str(). 128 | * 129 | * NOTE: To use the recommended 32 bit FNV-1 hash, use FNV1_32_INIT as the hval 130 | * argument on the first call to either fnv_32_buf() or fnv_32_str(). 131 | */ 132 | Fnv32_t 133 | fnv_32_str(char *str, Fnv32_t hval) 134 | { 135 | unsigned char *s = (unsigned char *)str; /* unsigned string */ 136 | 137 | /* 138 | * FNV-1 hash each octet in the buffer 139 | */ 140 | while (*s) { 141 | 142 | /* multiply by the 32 bit FNV magic prime mod 2^32 */ 143 | #if defined(NO_FNV_GCC_OPTIMIZATION) 144 | hval *= FNV_32_PRIME; 145 | #else 146 | hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); 147 | #endif 148 | 149 | /* xor the bottom with the current octet */ 150 | hval ^= (Fnv32_t)*s++; 151 | } 152 | 153 | /* return our new hash value */ 154 | return hval; 155 | } 156 | -------------------------------------------------------------------------------- /source/Hash_fnv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fnv - Fowler/Noll/Vo- hash code 3 | * 4 | * @(#) $Revision: 1.5 $ 5 | * @(#) $Id: fnv.h,v 1.5 2003/10/03 20:35:52 chongo Exp $ 6 | * @(#) $Source: /usr/local/src/cmd/fnv/RCS/fnv.h,v $ 7 | * 8 | *** 9 | * 10 | * Fowler/Noll/Vo- hash 11 | * 12 | * The basis of this hash algorithm was taken from an idea sent 13 | * as reviewer comments to the IEEE POSIX P1003.2 committee by: 14 | * 15 | * Phong Vo (http://www.research.att.com/info/kpv/) 16 | * Glenn Fowler (http://www.research.att.com/~gsf/) 17 | * 18 | * In a subsequent ballot round: 19 | * 20 | * Landon Curt Noll (http://www.isthe.com/chongo/) 21 | * 22 | * improved on their algorithm. Some people tried this hash 23 | * and found that it worked rather well. In an EMail message 24 | * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. 25 | * 26 | * FNV hashes are designed to be fast while maintaining a low 27 | * collision rate. The FNV speed allows one to quickly hash lots 28 | * of data while maintaining a reasonable collision rate. See: 29 | * 30 | * http://www.isthe.com/chongo/tech/comp/fnv/index.html 31 | * 32 | * for more details as well as other forms of the FNV hash. 33 | * 34 | *** 35 | * 36 | * NOTE: The FNV-0 historic hash is not recommended. One should use 37 | * the FNV-1 hash instead. 38 | * 39 | * To use the 32 bit FNV-0 historic hash, pass FNV0_32_INIT as the 40 | * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). 41 | * 42 | * To use the 64 bit FNV-0 historic hash, pass FNV0_64_INIT as the 43 | * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str(). 44 | * 45 | * To use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the 46 | * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). 47 | * 48 | * To use the recommended 64 bit FNV-1 hash, pass FNV1_64_INIT as the 49 | * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str(). 50 | * 51 | * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the 52 | * Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str(). 53 | * 54 | * To use the recommended 64 bit FNV-1a hash, pass FNV1_64A_INIT as the 55 | * Fnv64_t hashval argument to fnv_64a_buf() or fnv_64a_str(). 56 | * 57 | *** 58 | * 59 | * Please do not copyright this code. This code is in the public domain. 60 | * 61 | * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 62 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 63 | * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 64 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 65 | * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 66 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 67 | * PERFORMANCE OF THIS SOFTWARE. 68 | * 69 | * By: 70 | * chongo /\oo/\ 71 | * http://www.isthe.com/chongo/ 72 | * 73 | * Share and Enjoy! :-) 74 | */ 75 | 76 | #if !defined(__FNV_H__) 77 | #define __FNV_H__ 78 | 79 | 80 | /* 81 | * 32 bit FNV-0 hash type 82 | */ 83 | typedef unsigned long Fnv32_t; 84 | 85 | 86 | /* 87 | * 32 bit FNV-0 zero initial basis 88 | * 89 | * This historic hash is not recommended. One should use 90 | * the FNV-1 hash and initial basis instead. 91 | */ 92 | #define FNV0_32_INIT ((Fnv32_t)0) 93 | 94 | 95 | /* 96 | * 32 bit FNV-1 and FNV-1a non-zero initial basis 97 | * 98 | * The FNV-1 initial basis is the FNV-0 hash of the following 32 octets: 99 | * 100 | * chongo /\../\ 101 | * 102 | * NOTE: The \'s above are not back-slashing escape characters. 103 | * They are literal ASCII backslash 0x5c characters. 104 | * 105 | * NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition. 106 | */ 107 | #define FNV1_32_INIT ((Fnv32_t)0x811c9dc5) 108 | #define FNV1_32A_INIT FNV1_32_INIT 109 | 110 | 111 | /* 112 | * determine how 64 bit unsigned values are represented 113 | */ 114 | //#include "longlong.h" 115 | 116 | 117 | /* 118 | * 64 bit FNV-0 hash 119 | */ 120 | #if defined(HAVE_64BIT_LONG_LONG) 121 | typedef unsigned long long Fnv64_t; 122 | #else 123 | typedef struct { 124 | unsigned long w32[2]; 125 | } Fnv64_t; 126 | #endif 127 | 128 | 129 | /* 130 | * 64 bit FNV-0 zero initial basis 131 | * 132 | * This historic hash is not recommended. One should use 133 | * the FNV-1 hash and initial basis instead. 134 | */ 135 | #if defined(HAVE_64BIT_LONG_LONG) 136 | #define FNV0_64_INIT ((Fnv64_t)0) 137 | #else 138 | extern const Fnv64_t fnv1_64_init; 139 | #define FNV0_64_INIT (fnv1_64_init) 140 | #endif 141 | 142 | 143 | /* 144 | * 64 bit FNV-1 non-zero initial basis 145 | * 146 | * The FNV-1 initial basis is the FNV-0 hash of the following 32 octets: 147 | * 148 | * chongo /\../\ 149 | * 150 | * NOTE: The \'s above are not back-slashing escape characters. 151 | * They are literal ASCII backslash 0x5c characters. 152 | * 153 | * NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition. 154 | */ 155 | #if defined(HAVE_64BIT_LONG_LONG) 156 | #define FNV1_64_INIT ((Fnv64_t)0xcbf29ce484222325ULL) 157 | #define FNV1_64A_INIT FNV1_64_INIT 158 | #else 159 | extern const Fnv64_t fnv1_64_init; 160 | extern const Fnv64_t fnv1_64a_init; 161 | #define FNV1_64_INIT (fnv1_64_init) 162 | #define FNV1_64A_INIT FNV1_64_INIT 163 | #endif 164 | 165 | 166 | /* 167 | * external functions 168 | */ 169 | extern Fnv32_t fnv_32_buf(void *buf, size_t len, Fnv32_t hashval); 170 | extern Fnv32_t fnv_32_str(char *buf, Fnv32_t hashval); 171 | extern Fnv64_t fnv_64_buf(void *buf, size_t len, Fnv64_t hashval); 172 | extern Fnv64_t fnv_64_str(char *buf, Fnv64_t hashval); 173 | extern Fnv32_t fnv_32a_buf(void *buf, size_t len, Fnv32_t hashval); 174 | extern Fnv32_t fnv_32a_str(char *buf, Fnv32_t hashval); 175 | extern Fnv64_t fnv_64a_buf(void *buf, size_t len, Fnv64_t hashval); 176 | extern Fnv64_t fnv_64a_str(char *buf, Fnv64_t hashval); 177 | 178 | 179 | #endif /* __FNV_H__ */ -------------------------------------------------------------------------------- /source/Hash_murmur.c: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // MurmurHash2, by Austin Appleby 3 | 4 | // Note - This code makes a few assumptions about how your machine behaves - 5 | 6 | // 1. We can read a 4-byte value from any address without crashing 7 | // 2. sizeof(int) == 4 8 | 9 | // And it has a few limitations - 10 | 11 | // 1. It will not work incrementally. 12 | // 2. It will not produce the same results on little-endian and big-endian 13 | // machines. 14 | 15 | unsigned int MurmurHash2 ( const void * key, int len, unsigned int seed ) 16 | { 17 | // 'm' and 'r' are mixing constants generated offline. 18 | // They're not really 'magic', they just happen to work well. 19 | 20 | const unsigned int m = 0x5bd1e995; 21 | const int r = 24; 22 | 23 | // Initialize the hash to a 'random' value 24 | 25 | unsigned int h = seed ^ len; 26 | 27 | // Mix 4 bytes at a time into the hash 28 | 29 | const unsigned char * data = (const unsigned char *)key; 30 | 31 | while(len >= 4) 32 | { 33 | unsigned int k = *(unsigned int *)data; 34 | 35 | k *= m; 36 | k ^= k >> r; 37 | k *= m; 38 | 39 | h *= m; 40 | h ^= k; 41 | 42 | data += 4; 43 | len -= 4; 44 | } 45 | 46 | // Handle the last few bytes of the input array 47 | 48 | switch(len) 49 | { 50 | case 3: h ^= data[2] << 16; 51 | case 2: h ^= data[1] << 8; 52 | case 1: h ^= data[0]; 53 | h *= m; 54 | }; 55 | 56 | // Do a few final mixes of the hash to ensure the last few 57 | // bytes are well-incorporated. 58 | 59 | h ^= h >> 13; 60 | h *= m; 61 | h ^= h >> 15; 62 | 63 | return h; 64 | } 65 | -------------------------------------------------------------------------------- /source/Hash_murmur.h: -------------------------------------------------------------------------------- 1 | unsigned int MurmurHash2(const void *key, int len, unsigned int seed); 2 | -------------------------------------------------------------------------------- /source/Hash_superfast.c: -------------------------------------------------------------------------------- 1 | //#include "pstdint.h" /* Replace with if appropriate */ 2 | #include "Common.h" 3 | 4 | #undef get16bits 5 | #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ 6 | || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) 7 | #define get16bits(d) (*((const uint16_t *) (d))) 8 | #endif 9 | 10 | #if !defined (get16bits) 11 | #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\ 12 | +(uint32_t)(((const uint8_t *)(d))[0]) ) 13 | #endif 14 | 15 | uint32_t SuperFastHash (const char * data, int len) 16 | { 17 | uint32_t hash = len, tmp; 18 | int rem; 19 | 20 | if (len <= 0 || data == NULL) return 0; 21 | 22 | rem = len & 3; 23 | len >>= 2; 24 | 25 | /* Main loop */ 26 | for (;len > 0; len--) { 27 | hash += get16bits (data); 28 | tmp = (get16bits (data+2) << 11) ^ hash; 29 | hash = (hash << 16) ^ tmp; 30 | data += 2*sizeof (uint16_t); 31 | hash += hash >> 11; 32 | } 33 | 34 | /* Handle end cases */ 35 | switch (rem) { 36 | case 3: hash += get16bits (data); 37 | hash ^= hash << 16; 38 | hash ^= data[sizeof (uint16_t)] << 18; 39 | hash += hash >> 11; 40 | break; 41 | case 2: hash += get16bits (data); 42 | hash ^= hash << 11; 43 | hash += hash >> 17; 44 | break; 45 | case 1: hash += *data; 46 | hash ^= hash << 10; 47 | hash += hash >> 1; 48 | } 49 | 50 | /* Force "avalanching" of final 127 bits */ 51 | hash ^= hash << 3; 52 | hash += hash >> 5; 53 | hash ^= hash << 4; 54 | hash += hash >> 17; 55 | hash ^= hash << 25; 56 | hash += hash >> 6; 57 | 58 | return hash; 59 | } 60 | -------------------------------------------------------------------------------- /source/Hash_superfast.h: -------------------------------------------------------------------------------- 1 | uint32_t SuperFastHash (const char * data, int len); -------------------------------------------------------------------------------- /source/List.c: -------------------------------------------------------------------------------- 1 | //metadoc List copyright Steve Dekorte 2002 2 | //metadoc List license BSD revised 3 | 4 | #define LIST_C 5 | #include "List.h" 6 | #undef LIST_C 7 | #include 8 | 9 | List *List_new(void) 10 | { 11 | List *self = (List *)io_calloc(1, sizeof(List)); 12 | self->size = 0; 13 | self->memSize = sizeof(void *)*LIST_START_SIZE; 14 | self->items = (void **)io_calloc(1, self->memSize); 15 | return self; 16 | } 17 | 18 | List *List_clone(const List *self) 19 | { 20 | List *child = List_new(); 21 | List_copy_(child, self); 22 | /* 23 | List *child = cpalloc(self, sizeof(List)); 24 | child->items = cpalloc(self->items, self->memSize); 25 | */ 26 | return child; 27 | } 28 | 29 | static size_t indexWrap(long index, size_t size) 30 | { 31 | if (index < 0) 32 | { 33 | index = size - index; 34 | 35 | if (index < 0) 36 | { 37 | index = 0; 38 | } 39 | } 40 | 41 | if (index > (int)size) 42 | { 43 | index = size; 44 | } 45 | 46 | return (size_t)index; 47 | } 48 | 49 | void List_sliceInPlace(List* self, long startIndex, long endIndex) 50 | { 51 | size_t i, size = List_size(self); 52 | List *tmp = List_new(); 53 | size_t start = indexWrap(startIndex, size); 54 | size_t end = indexWrap(endIndex, size); 55 | 56 | for (i = start; i < size && i < end + 1; i ++) 57 | { 58 | List_append_(tmp, List_at_(self, i)); 59 | } 60 | 61 | List_copy_(self, tmp); 62 | List_free(tmp); 63 | } 64 | 65 | List *List_cloneSlice(const List *self, long startIndex, long endIndex) 66 | { 67 | List *child = List_clone(self); 68 | List_sliceInPlace(child, startIndex, endIndex); 69 | return child; 70 | } 71 | 72 | void List_free(List *self) 73 | { 74 | //printf("List_free(%p)\n", (void *)self); 75 | io_free(self->items); 76 | io_free(self); 77 | } 78 | 79 | UArray List_asStackAllocatedUArray(List *self) 80 | { 81 | UArray a = UArray_stackAllocedEmptyUArray(); 82 | a.itemType = CTYPE_uintptr_t; 83 | a.itemSize = sizeof(uintptr_t); 84 | a.size = self->size; 85 | a.data = (uint8_t *)(self->items); 86 | return a; 87 | } 88 | 89 | size_t List_memorySize(const List *self) 90 | { 91 | return sizeof(List) + (self->size * sizeof(void *)); 92 | } 93 | 94 | void List_removeAll(List *self) 95 | { 96 | self->size = 0; 97 | List_compactIfNeeded(self); 98 | } 99 | 100 | void List_copy_(List *self, const List *otherList) 101 | { 102 | if (self == otherList || (!otherList->size && !self->size)) 103 | { 104 | return; 105 | } 106 | 107 | List_preallocateToSize_(self, otherList->size); 108 | memmove(self->items, otherList->items, sizeof(void *) * (otherList->size)); 109 | self->size = otherList->size; 110 | } 111 | 112 | int List_equals_(const List *self, const List *otherList) 113 | { 114 | return (self->size == otherList->size && 115 | memcmp(self->items, otherList->items, sizeof(void *) * self->size) == 0); 116 | } 117 | 118 | /* --- sizing ------------------------------------------------ */ 119 | 120 | void List_setSize_(List *self, size_t index) 121 | { 122 | List_ifNeededSizeTo_(self, index); 123 | self->size = index; 124 | } 125 | 126 | void List_preallocateToSize_(List *self, size_t index) 127 | { 128 | size_t s = index * sizeof(void *); 129 | 130 | if (s >= self->memSize) 131 | { 132 | size_t newSize = self->memSize * LIST_RESIZE_FACTOR; 133 | 134 | if (s > newSize) 135 | { 136 | newSize = s; 137 | } 138 | 139 | self->items = (void **)io_realloc(self->items, newSize); 140 | memset(self->items + self->size, 0, (newSize - (self->size*sizeof(void *)))); 141 | self->memSize = newSize; 142 | } 143 | } 144 | 145 | void List_compact(List *self) 146 | { 147 | self->memSize = self->size * sizeof(void *); 148 | self->items = (void **)io_realloc(self->items, self->memSize); 149 | } 150 | 151 | // ----------------------------------------------------------- 152 | 153 | void List_print(const List *self) 154 | { 155 | size_t i; 156 | 157 | printf("List <%p> [%i bytes]\n", (void *)self, (int)self->memSize); 158 | 159 | for (i = 0; i < self->size; i ++) 160 | { 161 | printf("%i: %p\n", (int)i, (void *)self->items[i]); 162 | } 163 | 164 | printf("\n"); 165 | } 166 | 167 | // enumeration ----------------------------------------- 168 | 169 | void List_do_(List *self, ListDoCallback *callback) 170 | { 171 | LIST_FOREACH(self, i, v, if (v) (*callback)(v)); 172 | } 173 | 174 | void List_do_with_(List *self, ListDoWithCallback *callback, void *arg) 175 | { 176 | LIST_FOREACH(self, i, v, if (v) (*callback)(v, arg)); 177 | } 178 | 179 | void List_mapInPlace_(List *self, ListCollectCallback *callback) 180 | { 181 | void **items = self->items; 182 | LIST_FOREACH(self, i, v, items[i] = (*callback)(v)); 183 | } 184 | 185 | List *List_map_(List *self, ListCollectCallback *callback) 186 | { 187 | List *r = List_new(); 188 | LIST_FOREACH(self, i, v, List_append_(r, (*callback)(v));); 189 | return r; 190 | } 191 | 192 | List *List_select_(List *self, ListSelectCallback *callback) 193 | { 194 | List *r = List_new(); 195 | LIST_FOREACH(self, i, v, if ((*callback)(v)) List_append_(r, v)); 196 | return r; 197 | } 198 | 199 | void *List_detect_(List *self, ListDetectCallback *callback) 200 | { 201 | LIST_FOREACH(self, i, v, if (v && (*callback)(v)) return v; ); 202 | return NULL; 203 | } 204 | 205 | void *List_anyOne(const List *self) 206 | { 207 | size_t i; 208 | 209 | if (self->size == 0) 210 | { 211 | return (void *)NULL; 212 | } 213 | 214 | if (self->size == 1) 215 | { 216 | return LIST_AT_(self, 0); 217 | } 218 | 219 | i = (rand() >> 4) % (self->size); // without the shift, just get a sequence! 220 | 221 | return LIST_AT_(self, i); 222 | } 223 | 224 | void List_shuffle(List *self) 225 | { 226 | size_t i, j; 227 | 228 | for (i = 0; i < self->size - 1; i ++) 229 | { 230 | j = i + rand() % (self->size - i); 231 | List_swap_with_(self, i, j); 232 | } 233 | } 234 | 235 | void *List_removeLast(List *self) 236 | { 237 | void *item = List_at_(self, self->size - 1); 238 | 239 | if (item) 240 | { 241 | self->size --; 242 | List_compactIfNeeded(self); 243 | } 244 | 245 | return item; 246 | } 247 | 248 | -------------------------------------------------------------------------------- /source/List.h: -------------------------------------------------------------------------------- 1 | //metadoc List copyright Steve Dekorte 2002 2 | //metadoc List license BSD revised 3 | /*metadoc List description 4 | List - an array of void pointers 5 | User is responsible for io_freeing items 6 | */ 7 | 8 | #ifndef LIST_DEFINED 9 | #define LIST_DEFINED 1 10 | 11 | #include "Common.h" 12 | #include "PortableSorting.h" 13 | #include 14 | #include 15 | #include 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | #ifdef LOW_MEMORY_SYSTEM 22 | #define LIST_START_SIZE 1 23 | #define LIST_RESIZE_FACTOR 2 24 | #else 25 | #define LIST_START_SIZE 1 26 | #define LIST_RESIZE_FACTOR 2 27 | #endif 28 | 29 | #define LIST_AT_(self, n) self->items[n] 30 | 31 | 32 | typedef void (ListDoCallback)(void *); 33 | typedef void (ListDoWithCallback)(void *, void *); 34 | typedef void *(ListCollectCallback)(void *); 35 | typedef int (ListSelectCallback)(void *); 36 | typedef int (ListDetectCallback)(void *); 37 | typedef int (ListSortCallback)(const void *, const void *); 38 | typedef int (ListSortRCallback)(void *, const void *, const void *); 39 | typedef int (ListCompareFunc)(const void *, const void *); 40 | 41 | typedef struct 42 | { 43 | void **items; 44 | size_t size; 45 | size_t memSize; 46 | } List; 47 | 48 | typedef struct 49 | { 50 | List *list; 51 | size_t index; 52 | } ListCursor; 53 | 54 | BASEKIT_API List *List_new(void); 55 | BASEKIT_API List *List_clone(const List *self); 56 | BASEKIT_API List *List_cloneSlice(const List *self, long startIndex, long endIndex); 57 | 58 | BASEKIT_API void List_free(List *self); 59 | BASEKIT_API void List_removeAll(List *self); 60 | BASEKIT_API void List_copy_(List *self, const List *otherList); 61 | BASEKIT_API int List_equals_(const List *self, const List *otherList); 62 | BASEKIT_API size_t List_memorySize(const List *self); 63 | 64 | #include "UArray.h" 65 | 66 | BASEKIT_API UArray List_asStackAllocatedUArray(List *self); 67 | 68 | // sizing 69 | 70 | BASEKIT_API void List_preallocateToSize_(List *self, size_t index); 71 | BASEKIT_API void List_setSize_(List *self, size_t index); 72 | BASEKIT_API void List_compact(List *self); 73 | 74 | // utility 75 | 76 | BASEKIT_API void List_print(const List *self); 77 | BASEKIT_API void List_sliceInPlace(List *self, long startIndex, long endIndex); 78 | 79 | // enumeration 80 | 81 | BASEKIT_API void List_do_(List *self, ListDoCallback *callback); 82 | BASEKIT_API void List_do_with_(List *self, ListDoWithCallback *callback, void *arg); 83 | 84 | BASEKIT_API List *List_map_(List *self, ListCollectCallback *callback); 85 | BASEKIT_API void List_mapInPlace_(List *self, ListCollectCallback *callback); 86 | BASEKIT_API void *List_detect_(List *self, ListDetectCallback *callback); 87 | BASEKIT_API List *List_select_(List *self, ListSelectCallback *callback); 88 | 89 | BASEKIT_API void *List_anyOne(const List *self); 90 | BASEKIT_API void List_shuffle(List *self); 91 | BASEKIT_API void *List_removeLast(List *self); 92 | 93 | #include "List_inline.h" 94 | 95 | #ifdef __cplusplus 96 | } 97 | #endif 98 | #endif 99 | -------------------------------------------------------------------------------- /source/List_inline.h: -------------------------------------------------------------------------------- 1 | //metadoc List copyright Steve Dekorte 2002 2 | //metadoc List license BSD revised 3 | /*metadoc List description 4 | List is an array of void pointers. 5 | The List is not responsible for io_freeing it's elements. 6 | */ 7 | 8 | #ifdef LIST_C 9 | #define IO_IN_C_FILE 10 | #endif 11 | #include "Common_inline.h" 12 | #include "PortableSorting.h" 13 | #ifdef IO_DECLARE_INLINES 14 | 15 | #define LIST_FOREACH(list, index, value, code) \ 16 | { \ 17 | const List *foreachList = list; \ 18 | size_t index, foreachMax = foreachList->size; \ 19 | \ 20 | for (index = 0; index < foreachMax; index ++) \ 21 | { \ 22 | void *value = foreachList->items[index]; \ 23 | code; \ 24 | } \ 25 | } 26 | 27 | #define LIST_SAFEFOREACH(list, index, value, code) \ 28 | { \ 29 | const List *foreachList = list; \ 30 | size_t index; \ 31 | \ 32 | for (index = 0; index < List_size(foreachList); index ++) \ 33 | { \ 34 | void *value = List_at_(foreachList, index); \ 35 | code; \ 36 | } \ 37 | } 38 | 39 | #define LIST_REVERSEFOREACH(list, index, value, code) \ 40 | { \ 41 | const List *foreachList = list; \ 42 | size_t index = List_size(foreachList); \ 43 | \ 44 | while (index) \ 45 | { \ 46 | void *value = List_at_(foreachList, (index --)); \ 47 | code; \ 48 | } \ 49 | } 50 | 51 | #define LIST_SAFEREVERSEFOREACH(list, index, value, code) \ 52 | { \ 53 | const List *foreachList = list; \ 54 | size_t index = List_size(foreachList); \ 55 | \ 56 | for (index = List_size(foreachList) - 1; index > 0; index --) \ 57 | { \ 58 | void *value = List_at_(foreachList, index); \ 59 | code; \ 60 | if (index > List_size(foreachList) - 1) { index = List_size(foreachList) - 1; } \ 61 | } \ 62 | } 63 | 64 | #define LIST_DO_(list, func) \ 65 | { \ 66 | const List *foreachList = list; \ 67 | size_t index, foreachMax = List_size(foreachList); \ 68 | \ 69 | for (index = 0; index < foreachMax; index ++) \ 70 | { \ 71 | func(List_at_(foreachList, index)); \ 72 | } \ 73 | } 74 | 75 | IOINLINE size_t List_size(const List *self) 76 | { 77 | return self->size; 78 | } 79 | 80 | IOINLINE void List_ifNeededSizeTo_(List *self, size_t newSize) 81 | { 82 | if (newSize * sizeof(void *) >= self->memSize) 83 | { 84 | List_preallocateToSize_(self, newSize); 85 | } 86 | } 87 | 88 | IOINLINE void *List_rawAt_(List *self, size_t index) 89 | { 90 | return self->items[index]; 91 | } 92 | 93 | 94 | IOINLINE void *List_at_(const List *self, size_t index) 95 | { 96 | if (index < self->size) 97 | { 98 | return self->items[index]; 99 | } 100 | 101 | return (void *)NULL; 102 | } 103 | 104 | // -------------------------------------------- 105 | 106 | IOINLINE size_t List_indexOf_(List *self, void *item) 107 | { 108 | LIST_FOREACH(self, i, v, if(v == item) return i); 109 | return -1; 110 | } 111 | 112 | IOINLINE int List_contains_(List *self, void *item) 113 | { 114 | LIST_FOREACH(self, i, v, if(v == item) return 1); 115 | return 0; 116 | } 117 | 118 | IOINLINE void *List_append_(List *self, void *item) 119 | { 120 | List_ifNeededSizeTo_(self, self->size + 1); 121 | self->items[self->size] = item; 122 | self->size ++; 123 | return item; 124 | } 125 | 126 | IOINLINE void List_appendSeq_(List *self, const List *otherList) 127 | { 128 | LIST_FOREACH(otherList, i, v, List_append_(self, v)); 129 | } 130 | 131 | IOINLINE void List_compactIfNeeded(List *self) 132 | { 133 | if(self->memSize > 1024 && self->size * sizeof(void *) * 4 < self->memSize) 134 | { 135 | List_compact(self); 136 | } 137 | } 138 | 139 | IOINLINE void List_removeIndex_(List *self, size_t index) 140 | { 141 | if (index >= 0 && index < self->size) 142 | { 143 | if ( index != self->size - 1) 144 | { 145 | memmove(&self->items[index], &self->items[index + 1], 146 | (self->size - 1 - index) * sizeof(void *)); 147 | } 148 | 149 | self->size --; 150 | 151 | List_compactIfNeeded(self); 152 | } 153 | } 154 | 155 | IOINLINE void List_removeIndex_toIndex_(List *self, size_t index1, size_t index2) 156 | { 157 | size_t length; 158 | 159 | if (index1 < 0) 160 | { 161 | index1 = 0; 162 | } 163 | 164 | if (index1 > self->size - 1) 165 | { 166 | index1 = self->size - 1; 167 | } 168 | 169 | if (index2 < 0) 170 | { 171 | index2 = 0; 172 | } 173 | 174 | if (index2 > self->size - 1) 175 | { 176 | index2 = self->size - 1; 177 | } 178 | 179 | length = index2 - index1; 180 | 181 | if (length <= 0) 182 | { 183 | return; 184 | } 185 | 186 | memmove(&self->items[index1], &self->items[index2], 187 | (self->size - index2) * sizeof(void *)); 188 | 189 | self->size -= length; 190 | 191 | List_compactIfNeeded(self); 192 | } 193 | 194 | IOINLINE void List_remove_(List *self, void *item) 195 | { 196 | size_t index; 197 | 198 | for (index = 0; index < self->size; index ++) 199 | { 200 | if (self->items[index] == item) 201 | { 202 | List_removeIndex_(self, index); 203 | } 204 | } 205 | } 206 | 207 | IOINLINE int List_removeFirst_(List *self, void *item) 208 | { 209 | size_t i, max = self->size; 210 | 211 | for (i = 0; i < max; i ++) 212 | { 213 | if (self->items[i] == item) 214 | { 215 | List_removeIndex_(self, i); 216 | return 1; 217 | } 218 | } 219 | 220 | return 0; 221 | } 222 | 223 | IOINLINE void List_removeLast_(List *self, void *item) 224 | { 225 | size_t index = self->size - 1; 226 | 227 | for (index = self->size - 1; index > -1; index --) 228 | { 229 | if (self->items[index] == item) 230 | { 231 | List_removeIndex_(self, index); 232 | break; 233 | } 234 | } 235 | } 236 | 237 | IOINLINE void List_removeItems_(List *self, List *other) 238 | { 239 | LIST_FOREACH(other, i, v, List_remove_(self, v)); 240 | } 241 | 242 | IOINLINE void List_at_insert_(List *self, size_t index, void *item) 243 | { 244 | if (index < 0) 245 | { 246 | return; 247 | } 248 | 249 | if (index > self->size - 1) 250 | { 251 | List_preallocateToSize_(self, index + 1); 252 | } 253 | else 254 | { 255 | List_ifNeededSizeTo_(self, self->size + 1); 256 | } 257 | 258 | memmove(&self->items[index + 1], &self->items[index], 259 | (self->size - index) * sizeof(void *)); 260 | 261 | self->items[index] = item; 262 | self->size ++; 263 | } 264 | 265 | IOINLINE void List_at_put_(List *self, size_t index, void *item) 266 | { 267 | if (index < 0) 268 | { 269 | return; 270 | } 271 | 272 | List_ifNeededSizeTo_(self, index); 273 | self->items[index] = item; 274 | 275 | if (index + 1 > self->size) 276 | { 277 | self->size = index + 1; 278 | } 279 | } 280 | 281 | IOINLINE void List_swap_with_(List *self, long index1, long index2) 282 | { 283 | if (index1 < 0 || index2 < 0) 284 | { 285 | return; 286 | } 287 | 288 | if (index1 != index2) 289 | { 290 | void **items = self->items; 291 | register void *v1 = items[index1]; 292 | 293 | items[index1] = items[index2]; 294 | items[index2] = v1; 295 | } 296 | } 297 | 298 | IOINLINE void List_reverseInPlace(List *self) 299 | { 300 | register void **i = self->items; 301 | register void **j = i + (self->size - 1); 302 | register void *iv; 303 | 304 | while (j > i) 305 | { 306 | iv = *i; 307 | *i = *j; 308 | *j = iv; 309 | j --; 310 | i ++; 311 | } 312 | } 313 | 314 | // stack -------------------------------------------------- 315 | 316 | IOINLINE void List_push_(List *self, void *item) 317 | { 318 | List_ifNeededSizeTo_(self, self->size + 1); 319 | self->items[self->size] = item; 320 | self->size ++; 321 | } 322 | 323 | IOINLINE void *List_pop(List *self) 324 | { 325 | void *item; 326 | 327 | if (!self->size) 328 | { 329 | return (void *)NULL; 330 | } 331 | 332 | self->size --; 333 | item = self->items[self->size]; 334 | List_compactIfNeeded(self); 335 | return item; 336 | } 337 | 338 | IOINLINE void *List_top(const List *self) 339 | { 340 | if (!self->size) 341 | { 342 | return (void *)NULL; 343 | } 344 | 345 | return self->items[self->size - 1]; 346 | } 347 | 348 | /* --- perform -------------------------------------------------- */ 349 | 350 | IOINLINE int List_removeTrueFor_(List *self, ListCollectCallback* callback) 351 | { 352 | size_t getIndex = 0; 353 | size_t putIndex = 0; 354 | size_t count = self->size; 355 | void **items = self->items; 356 | 357 | while (getIndex < count) 358 | { 359 | void *item = items[getIndex]; 360 | 361 | if (item && !((*callback)(item))) 362 | { 363 | if (getIndex!=putIndex) 364 | { 365 | items[putIndex] = item; 366 | } 367 | 368 | putIndex ++; 369 | } 370 | 371 | getIndex ++; 372 | } 373 | 374 | self->size = putIndex; 375 | 376 | return getIndex - putIndex; 377 | } 378 | 379 | IOINLINE void List_qsort(List *self, ListSortCallback *callback) 380 | { 381 | qsort(self->items, self->size, sizeof(void *), *callback); 382 | } 383 | 384 | IOINLINE void List_qsort_r(List *self, void *context, ListSortRCallback *callback) 385 | { 386 | portable_qsort_r(self->items, self->size, sizeof(void *), context, *callback); 387 | } 388 | 389 | IOINLINE void *List_bsearch(List *self, const void *key, ListSortCallback *callback) 390 | { 391 | return bsearch(key, self->items, self->size, sizeof(void *), callback); 392 | } 393 | 394 | IOINLINE void *List_first(const List *self) 395 | { 396 | return List_at_(self, 0); 397 | } 398 | 399 | IOINLINE void *List_last(List *self) 400 | { 401 | return List_at_(self, List_size(self) - 1); 402 | } 403 | 404 | #undef IO_IN_C_FILE 405 | #endif 406 | 407 | -------------------------------------------------------------------------------- /source/MainArgs.c: -------------------------------------------------------------------------------- 1 | //metadoc MainArgs copyright Steve Dekorte 2002 2 | //metadoc MainArgs license BSD revised 3 | 4 | #include "Base.h" 5 | #include 6 | #include 7 | #include 8 | #include "MainArgs.h" 9 | #include "PortableStrlcpy.h" 10 | 11 | MainArgs *MainArgs_new(void) 12 | { 13 | MainArgs *self = (MainArgs *)io_calloc(1, sizeof(MainArgs)); 14 | return self; 15 | } 16 | 17 | void MainArgs_free(MainArgs *self) 18 | { 19 | if (self->argv) 20 | { 21 | int i; 22 | 23 | for (i = 0; i < self->argc; i ++) 24 | { 25 | io_free((char *)(self->argv[i])); 26 | } 27 | 28 | io_free((void*)(self->argv)); 29 | } 30 | 31 | io_free(self); 32 | } 33 | 34 | void MainArgs_argc_argv_(MainArgs *self, int argc, const char **argv) 35 | { 36 | int i; 37 | 38 | self->argc = argc; 39 | // copy by reference since args should be retained on 40 | // the C stack until the program exits 41 | 42 | self->argv = (const char **)io_calloc(1, sizeof(char *)*argc); 43 | 44 | for (i = 0; i < argc; i ++) 45 | { 46 | const char *s = argv[i]; 47 | size_t len = strlen(s); 48 | char *ptr = (char *)io_calloc(1, len + 1); 49 | PortableStrlcpy(ptr, s, len + 1); 50 | self->argv[i] = ptr; 51 | 52 | //self->argv[i] = strcpy((char *)io_calloc(1, strlen(s)+1), s); 53 | /*printf("argv[%i] = '%s'\n", i, s);*/ 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /source/MainArgs.h: -------------------------------------------------------------------------------- 1 | //metadoc MainArgs copyright Steve Dekorte 2002 2 | //metadoc MainArgs license BSD revised 3 | /*metadoc MainArgs description 4 | Structure for copying and storing command line arguments.") 5 | */ 6 | 7 | #ifndef MAINARGS_DEFINED 8 | #define MAINARGS_DEFINED 1 9 | 10 | #include "Common.h" 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | typedef struct 17 | { 18 | int argc; 19 | const char **argv; 20 | } MainArgs; 21 | 22 | BASEKIT_API MainArgs *MainArgs_new(void); 23 | BASEKIT_API void MainArgs_free(MainArgs *self); 24 | 25 | BASEKIT_API void MainArgs_argc_argv_(MainArgs *self, int argc, const char **argv); 26 | #define MainArgs_argCount(self) self->argc 27 | #define MainArgs_argAt_(self, index) self->argv[index] 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | #endif 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /source/PointerHash.c: -------------------------------------------------------------------------------- 1 | //metadoc PointerHash copyright Steve Dekorte 2002 2 | //metadoc PointerHash license BSD revised 3 | //metadoc PointerHash notes Suggestion to use cuckoo hash and original implementation by Marc Fauconneau 4 | 5 | #define POINTERHASH_C 6 | #include "PointerHash.h" 7 | #undef POINTERHASH_C 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | PointerHash *PointerHash_new(void) 14 | { 15 | PointerHash *self = (PointerHash *)io_calloc(1, sizeof(PointerHash)); 16 | PointerHash_setSize_(self, 8); 17 | return self; 18 | } 19 | 20 | void PointerHash_copy_(PointerHash *self, const PointerHash *other) 21 | { 22 | io_free(self->records); 23 | memcpy(self, other, sizeof(PointerHash)); 24 | self->records = malloc(self->size * sizeof(PointerHashRecord)); 25 | memcpy(self->records, other->records, self->size * sizeof(PointerHashRecord)); 26 | } 27 | 28 | PointerHash *PointerHash_clone(PointerHash *self) 29 | { 30 | PointerHash *other = PointerHash_new(); 31 | PointerHash_copy_(other, self); 32 | return other; 33 | } 34 | 35 | void PointerHash_setSize_(PointerHash *self, size_t size) 36 | { 37 | self->records = realloc(self->records, size * sizeof(PointerHashRecord)); 38 | 39 | if(size > self->size) 40 | { 41 | memset(self->records + self->size * sizeof(PointerHashRecord), 42 | 0x0, (size - self->size) * sizeof(PointerHashRecord)); 43 | } 44 | 45 | self->size = size; 46 | 47 | PointerHash_updateMask(self); 48 | } 49 | 50 | void PointerHash_updateMask(PointerHash *self) 51 | { 52 | self->mask = (intptr_t)(self->size - 1); 53 | } 54 | 55 | void PointerHash_show(PointerHash *self) 56 | { 57 | size_t i; 58 | 59 | printf("PointerHash records:\n"); 60 | for(i = 0; i < self->size; i++) 61 | { 62 | PointerHashRecord *r = PointerHashRecords_recordAt_(self->records, i); 63 | printf(" %i: %p %p\n", (int)i, r->k, r->v); 64 | } 65 | } 66 | 67 | void PointerHash_free(PointerHash *self) 68 | { 69 | io_free(self->records); 70 | io_free(self); 71 | } 72 | 73 | void PointerHash_insert_(PointerHash *self, PointerHashRecord *x) 74 | { 75 | int n; 76 | 77 | for (n = 0; n < POINTERHASH_MAXLOOP; n ++) 78 | { 79 | PointerHashRecord *r; 80 | 81 | r = PointerHash_record1_(self, x->k); 82 | PointerHashRecord_swapWith_(x, r); 83 | if(x->k == 0x0) { self->keyCount ++; return; } 84 | 85 | r = PointerHash_record2_(self, x->k); 86 | PointerHashRecord_swapWith_(x, r); 87 | if(x->k == 0x0) { self->keyCount ++; return; } 88 | } 89 | 90 | PointerHash_grow(self); 91 | PointerHash_at_put_(self, x->k, x->v); 92 | } 93 | 94 | void PointerHash_insertRecords(PointerHash *self, unsigned char *oldRecords, size_t oldSize) 95 | { 96 | size_t i; 97 | 98 | for (i = 0; i < oldSize; i ++) 99 | { 100 | PointerHashRecord *r = PointerHashRecords_recordAt_(oldRecords, i); 101 | 102 | if (r->k) 103 | { 104 | PointerHash_at_put_(self, r->k, r->v); 105 | } 106 | } 107 | } 108 | 109 | void PointerHash_resizeTo_(PointerHash *self, size_t newSize) 110 | { 111 | unsigned char *oldRecords = self->records; 112 | size_t oldSize = self->size; 113 | self->size = newSize; 114 | self->records = io_calloc(1, sizeof(PointerHashRecord) * self->size); 115 | self->keyCount = 0; 116 | PointerHash_updateMask(self); 117 | PointerHash_insertRecords(self, oldRecords, oldSize); 118 | io_free(oldRecords); 119 | } 120 | 121 | void PointerHash_grow(PointerHash *self) 122 | { 123 | PointerHash_resizeTo_(self, self->size * 2); 124 | } 125 | 126 | void PointerHash_shrink(PointerHash *self) 127 | { 128 | PointerHash_resizeTo_(self, self->size / 2); 129 | } 130 | 131 | void PointerHash_removeKey_(PointerHash *self, void *k) 132 | { 133 | PointerHashRecord *r; 134 | 135 | r = PointerHash_record1_(self, k); 136 | if(r->k == k) 137 | { 138 | r->k = 0x0; 139 | r->v = 0x0; 140 | self->keyCount --; 141 | PointerHash_shrinkIfNeeded(self); 142 | return; 143 | } 144 | 145 | r = PointerHash_record2_(self, k); 146 | if(r->k == k) 147 | { 148 | r->k = 0x0; 149 | r->v = 0x0; 150 | self->keyCount --; 151 | PointerHash_shrinkIfNeeded(self); 152 | return; 153 | } 154 | } 155 | 156 | size_t PointerHash_size(PointerHash *self) // actually the keyCount 157 | { 158 | return self->keyCount; 159 | } 160 | 161 | // ---------------------------- 162 | 163 | size_t PointerHash_memorySize(PointerHash *self) 164 | { 165 | return sizeof(PointerHash) + self->size * sizeof(PointerHashRecord); 166 | } 167 | 168 | void PointerHash_compact(PointerHash *self) 169 | { 170 | } 171 | -------------------------------------------------------------------------------- /source/PointerHash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PointerHash.h 3 | * CuckooHashTable 4 | * 5 | * Created by Steve Dekorte on 2009 04 28. 6 | * Copyright 2009 __MyCompanyName__. All rights reserved. 7 | * 8 | */ 9 | 10 | #ifndef POINTERHASH_DEFINED 11 | #define POINTERHASH_DEFINED 1 12 | 13 | #include "Common.h" 14 | #include 15 | #include "PortableStdint.h" 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | #define POINTERHASH_MAXLOOP 10 22 | 23 | #include "PointerHash_struct.h" 24 | 25 | BASEKIT_API PointerHash *PointerHash_new(void); 26 | BASEKIT_API void PointerHash_copy_(PointerHash *self, const PointerHash *other); 27 | BASEKIT_API PointerHash *PointerHash_clone(PointerHash *self); 28 | BASEKIT_API void PointerHash_free(PointerHash *self); 29 | 30 | BASEKIT_API void PointerHash_at_put_(PointerHash *self, void *k, void *v); 31 | BASEKIT_API void PointerHash_removeKey_(PointerHash *self, void *k); 32 | BASEKIT_API size_t PointerHash_size(PointerHash *self); // actually the keyCount 33 | 34 | BASEKIT_API size_t PointerHash_memorySize(PointerHash *self); 35 | BASEKIT_API void PointerHash_compact(PointerHash *self); 36 | 37 | // --- private methods ---------------------------------------- 38 | 39 | BASEKIT_API void PointerHash_setSize_(PointerHash *self, size_t size); 40 | BASEKIT_API void PointerHash_insert_(PointerHash *self, PointerHashRecord *x); 41 | BASEKIT_API void PointerHash_grow(PointerHash *self); 42 | BASEKIT_API void PointerHash_shrinkIfNeeded(PointerHash *self); 43 | BASEKIT_API void PointerHash_shrink(PointerHash *self); 44 | BASEKIT_API void PointerHash_show(PointerHash *self); 45 | BASEKIT_API void PointerHash_updateMask(PointerHash *self); 46 | 47 | #include "PointerHash_inline.h" 48 | 49 | #define PointerHash_cleanSlots(self) 50 | #define PointerHash_hasDirtyKey_(self, k) 0 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | #endif 56 | -------------------------------------------------------------------------------- /source/PointerHash_inline.h: -------------------------------------------------------------------------------- 1 | //metadoc PointerHash copyright Steve Dekorte 2002, Marc Fauconneau 2007 2 | //metadoc PointerHash license BSD revised 3 | /*metadoc PointerHash description 4 | PointerHash - Cuckoo Hash 5 | keys and values are references (they are not copied or freed) 6 | key pointers are assumed unique 7 | */ 8 | 9 | #ifdef POINTERHASH_C 10 | #define IO_IN_C_FILE 11 | #endif 12 | #include "Common_inline.h" 13 | #ifdef IO_DECLARE_INLINES 14 | 15 | #define PointerHashRecords_recordAt_(records, pos) (PointerHashRecord *)(records + (pos * sizeof(PointerHashRecord))) 16 | 17 | /* 18 | IOINLINE unsigned int PointerHash_hash(PointerHash *self, void *key) 19 | { 20 | intptr_t k = (intptr_t)PointerHashKey_value(key); 21 | return k^(k>>4); 22 | } 23 | 24 | IOINLINE unsigned int PointerHash_hash_more(PointerHash *self, unsigned int hash) 25 | { 26 | return hash ^ (hash >> self->log2tableSize); 27 | } 28 | */ 29 | 30 | // ----------------------------------- 31 | 32 | IOINLINE PointerHashRecord *PointerHash_record1_(PointerHash *self, void *k) 33 | { 34 | // the ~| 0x1 before the mask ensures an odd pos 35 | intptr_t kk = (intptr_t)k; 36 | size_t pos = ((kk^(kk>>4)) | 0x1) & self->mask; 37 | return PointerHashRecords_recordAt_(self->records, pos); 38 | } 39 | 40 | IOINLINE PointerHashRecord *PointerHash_record2_(PointerHash *self, void *k) 41 | { 42 | // the | 0x1 before the mask ensures an even pos 43 | intptr_t kk = (intptr_t)k; 44 | //size_t pos = (((kk^(kk/33)) << 1)) & self->mask; 45 | size_t pos = (kk << 1) & self->mask; 46 | return PointerHashRecords_recordAt_(self->records, pos); 47 | } 48 | 49 | IOINLINE void *PointerHash_at_(PointerHash *self, void *k) 50 | { 51 | PointerHashRecord *r; 52 | 53 | r = PointerHash_record1_(self, k); 54 | if(k == r->k) return r->v; 55 | 56 | r = PointerHash_record2_(self, k); 57 | if(k == r->k) return r->v; 58 | 59 | return 0x0; 60 | } 61 | 62 | IOINLINE size_t PointerHash_count(PointerHash *self) 63 | { 64 | return self->keyCount; 65 | } 66 | 67 | IOINLINE int PointerHashKey_hasKey_(PointerHash *self, void *key) 68 | { 69 | return PointerHash_at_(self, key) != NULL; 70 | } 71 | 72 | IOINLINE void PointerHash_at_put_(PointerHash *self, void *k, void *v) 73 | { 74 | PointerHashRecord *r; 75 | 76 | r = PointerHash_record1_(self, k); 77 | 78 | if(!r->k) 79 | { 80 | r->k = k; 81 | r->v = v; 82 | self->keyCount ++; 83 | return; 84 | } 85 | 86 | if(r->k == k) 87 | { 88 | r->v = v; 89 | return; 90 | } 91 | 92 | r = PointerHash_record2_(self, k); 93 | 94 | if(!r->k) 95 | { 96 | r->k = k; 97 | r->v = v; 98 | self->keyCount ++; 99 | return; 100 | } 101 | 102 | if(r->k == k) 103 | { 104 | r->v = v; 105 | return; 106 | } 107 | 108 | { 109 | PointerHashRecord x; 110 | x.k = k; 111 | x.v = v; 112 | PointerHash_insert_(self, &x); 113 | } 114 | } 115 | 116 | IOINLINE void PointerHash_shrinkIfNeeded(PointerHash *self) 117 | { 118 | if(self->keyCount < self->size/8) 119 | { 120 | PointerHash_shrink(self); 121 | } 122 | } 123 | 124 | IOINLINE void PointerHashRecord_swapWith_(PointerHashRecord *self, PointerHashRecord *other) 125 | { 126 | PointerHashRecord tmp = *self; 127 | *self = *other; 128 | *other = tmp; 129 | } 130 | 131 | IOINLINE void PointerHash_clean(PointerHash *self) 132 | { 133 | memset(self->records, 0, sizeof(PointerHashRecord) * self->size); 134 | self->keyCount = 0; 135 | } 136 | 137 | // --- enumeration -------------------------------------------------- 138 | 139 | #define POINTERHASH_FOREACH(self, pkey, pvalue, code) \ 140 | {\ 141 | PointerHash *_self = (self);\ 142 | unsigned char *_records = _self->records;\ 143 | unsigned int _i, _size = _self->size;\ 144 | void *pkey;\ 145 | void *pvalue;\ 146 | \ 147 | for (_i = 0; _i < _size; _i ++)\ 148 | {\ 149 | PointerHashRecord *_record = PointerHashRecords_recordAt_(_records, _i);\ 150 | if (_record->k)\ 151 | {\ 152 | pkey = _record->k;\ 153 | pvalue = _record->v;\ 154 | code;\ 155 | }\ 156 | }\ 157 | } 158 | 159 | #undef IO_IN_C_FILE 160 | #endif 161 | -------------------------------------------------------------------------------- /source/PointerHash_struct.h: -------------------------------------------------------------------------------- 1 | // PointerHash.h 2 | // CuckooHashTable 3 | // Created by Steve Dekorte on 2009 04 28. 4 | 5 | #ifndef POINTERHASH_STRUCT_DEFINED 6 | #define POINTERHASH_STRUCT_DEFINED 1 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | typedef struct 13 | { 14 | void *k; 15 | void *v; 16 | } PointerHashRecord; 17 | 18 | typedef struct 19 | { 20 | unsigned char *records; 21 | size_t size; 22 | size_t keyCount; 23 | intptr_t mask; 24 | } PointerHash; 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | #endif 30 | -------------------------------------------------------------------------------- /source/PortableGettimeofday.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "PortableGettimeofday.h" 5 | 6 | #if defined(__WIN32__) || defined(WIN32) || defined(_WIN32) || defined(_MSC_VER) 7 | 8 | #if defined(__MINGW32__) && (3 < __MINGW32_MAJOR_VERSION || 3 == __MINGW32_MAJOR_VERSION && 9 < __MINGW32_MINOR_VERSION) 9 | #else 10 | 11 | #ifndef IO_ADDON_Sockets 12 | void gettimeofday(struct timeval *tv, struct timezone *tz) 13 | { 14 | TIME_ZONE_INFORMATION zoneInfo; 15 | 16 | struct _timeb timeb; 17 | _ftime_s(&timeb); 18 | 19 | tv->tv_sec = (long) timeb.time; 20 | tv->tv_usec = (long) (timeb.millitm * 1000); 21 | 22 | if (GetTimeZoneInformation(&zoneInfo) != TIME_ZONE_ID_INVALID) 23 | { 24 | tz->tz_minuteswest = zoneInfo.Bias; 25 | tz->tz_dsttime = 0; 26 | } 27 | else 28 | { 29 | tz->tz_minuteswest = 0; 30 | tz->tz_dsttime = 0; 31 | } 32 | } 33 | #endif 34 | #endif 35 | #else 36 | 37 | /* just to make compiler happy */ 38 | void PortableGettimeOfday(void) 39 | { 40 | } 41 | 42 | #endif 43 | 44 | double secondsSince1970(void) 45 | { 46 | double result; 47 | struct timeval tv; 48 | struct timezone tz; 49 | gettimeofday(&tv, &tz); 50 | result = tv.tv_sec; 51 | result += tv.tv_usec / 1000000.0; 52 | return result; 53 | } 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /source/PortableGettimeofday.h: -------------------------------------------------------------------------------- 1 | #ifndef PORTABLEGETTIMEOFDAY_DEFINED 2 | #define PORTABLEGETTIMEOFDAY_DEFINED 1 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #if defined(__WIN32__) || defined(WIN32) || defined(_WIN32) || defined(_MSC_VER) 9 | #if defined(_MSC_VER) 10 | #include 11 | /*struct timeval 12 | { 13 | long tv_sec; 14 | long tv_usec; 15 | };*/ 16 | #else 17 | /* for MingW */ 18 | #include 19 | #endif 20 | 21 | #if defined(__MINGW32__) && (3 < __MINGW32_MAJOR_VERSION || 3 == __MINGW32_MAJOR_VERSION && 9 < __MINGW32_MINOR_VERSION) 22 | #else 23 | struct timezone 24 | { 25 | int tz_minuteswest; /* of Greenwich */ 26 | int tz_dsttime; /* type of dst correction to apply */ 27 | }; 28 | 29 | #include "Common.h" 30 | BASEKIT_API extern void gettimeofday(struct timeval *tv, struct timezone *tz); 31 | #endif 32 | 33 | #else 34 | #include 35 | #endif 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | 41 | #endif 42 | 43 | double secondsSince1970(void); 44 | -------------------------------------------------------------------------------- /source/PortableSorting.c: -------------------------------------------------------------------------------- 1 | #include "PortableSorting.h" 2 | 3 | typedef struct 4 | { 5 | void *base; 6 | size_t size; 7 | size_t width; 8 | void *context; 9 | PortableSortingCompareCallback compare; 10 | unsigned char *swapSpace; 11 | } Sorter; 12 | 13 | void Sorter_quickSort(Sorter *self, size_t lb, size_t ub); 14 | size_t Sorter_quickSortRearrange(Sorter *self, size_t lb, size_t ub); 15 | 16 | void portable_qsort_r(void *base, size_t size, size_t width, 17 | void *context, PortableSortingCompareCallback compare) 18 | { 19 | if (size > 0 && width > 0) 20 | { 21 | Sorter s; 22 | s.base = base; 23 | s.size = size; 24 | s.width = width; 25 | s.context = context; 26 | s.compare = compare; 27 | s.swapSpace = malloc(width); 28 | Sorter_quickSort(&s, 0, size-1); 29 | free(s.swapSpace); 30 | } 31 | } 32 | 33 | void Sorter_quickSort(Sorter *self, size_t lb, size_t ub) 34 | { 35 | if (lb < ub) 36 | { 37 | size_t j = Sorter_quickSortRearrange(self, lb, ub); 38 | 39 | if (j) 40 | { 41 | Sorter_quickSort(self, lb, j - 1); 42 | } 43 | 44 | Sorter_quickSort(self, j + 1, ub); 45 | } 46 | } 47 | 48 | static void swap(void *base, size_t a, size_t b, size_t width, unsigned char *swapSpace) 49 | { 50 | //unsigned char swapSpace[width]; // windows can't deal with this 51 | void *ap = ((unsigned char *)base) + width*a; 52 | void *bp = ((unsigned char *)base) + width*b; 53 | memcpy(swapSpace, ap, width); 54 | memcpy(ap, bp, width); 55 | memcpy(bp, swapSpace, width); 56 | } 57 | 58 | size_t Sorter_quickSortRearrange(Sorter *self, size_t lb, size_t ub) 59 | { 60 | PortableSortingCompareCallback comp = self->compare; 61 | void *context = self->context; 62 | unsigned char *base = self->base; 63 | size_t width = self->width; 64 | 65 | do { 66 | while (ub > lb && (*comp)(context, base + width*ub, base + width*lb) >= 0) 67 | { 68 | ub --; 69 | } 70 | 71 | if (ub != lb) 72 | { 73 | swap(base, ub, lb, width, self->swapSpace); 74 | 75 | while (lb < ub && (*comp)(context, base + width*lb, base + width*ub) <= 0) 76 | { 77 | lb ++; 78 | } 79 | 80 | if (lb != ub) 81 | { 82 | swap(base, lb, ub, width, self->swapSpace); 83 | } 84 | } 85 | } while (lb != ub); 86 | 87 | return lb; 88 | } 89 | 90 | -------------------------------------------------------------------------------- /source/PortableSorting.h: -------------------------------------------------------------------------------- 1 | #ifndef PORTABLESORTING_DEFINED 2 | #define PORTABLESORTING_DEFINED 1 3 | 4 | #include "Common.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /* 11 | The reason for using this instead of C's qsort is 12 | that we need more context information than just the 13 | two objects if we want to do something like use an 14 | Io block to do the comparison and using globals is 15 | unacceptable for several reasons. 16 | 17 | qsort_r isn't available on all platforms. 18 | */ 19 | 20 | //typedef int (ListSortRCallback)(void *, const void *, const void *); 21 | 22 | typedef int (*PortableSortingCompareCallback)(void *context, const void *a, const void *b); 23 | 24 | BASEKIT_API void portable_qsort_r(void *base, size_t nel, size_t width, 25 | void *context, PortableSortingCompareCallback compare); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /source/PortableStrlcpy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998 Todd C. Miller 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. The name of the author may not be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 17 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 18 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 19 | * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include 29 | #include "PortableStrlcpy.h" 30 | 31 | /* 32 | * Copy src to string dest of size len. At most len-1 characters 33 | * will be copied. Always NUL terminates (unless len == 0). 34 | * Returns strlen(src); if retval >= len, truncation occurred. 35 | */ 36 | size_t PortableStrlcpy(char* dest, const char* src, size_t len) 37 | { 38 | char* d = dest; 39 | const char* s = src; 40 | size_t n = len; 41 | 42 | /* Copy as many bytes as will fit */ 43 | if (n != 0 && --n != 0) 44 | { 45 | do 46 | { 47 | if ((*d++ = *s++) == 0) 48 | break; 49 | } while (--n != 0); 50 | } 51 | 52 | /* Not enough room in dest, add NUL and traverse rest of src */ 53 | if (n == 0) 54 | { 55 | if (len != 0) 56 | *d = '\0'; /* NUL-terminate dest */ 57 | while (*s++); 58 | } 59 | 60 | return (s - src - 1); /* count doesn't include NUL */ 61 | } 62 | -------------------------------------------------------------------------------- /source/PortableStrlcpy.h: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | #include // size_t on windows 3 | #else 4 | #include // size_t 5 | #endif 6 | 7 | #define strlcpy(d, s, l) PortableStrlcpy((d), (s), (l)) 8 | 9 | size_t PortableStrlcpy(char*, const char*, size_t); 10 | -------------------------------------------------------------------------------- /source/PortableStrptime.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | /*#ifdef IO_NEEDS_STRPTIME */ 8 | char *io_strptime(char *buf, char *fmt, struct tm *tm); 9 | /*#endif*/ 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | -------------------------------------------------------------------------------- /source/PortableTruncate.c: -------------------------------------------------------------------------------- 1 | 2 | #include "PortableTruncate.h" 3 | 4 | 5 | int PortableTruncate_justHereToAvoidRanlibWarning(void) { return 0; } 6 | 7 | #ifdef _WIN32 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | // Win32 truncate by Mike Austin 15 | 16 | int truncate(const char *path, long length) 17 | { 18 | HANDLE file = CreateFile(path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 19 | FILE_SHARE_WRITE | FILE_SHARE_READ, NULL); 20 | 21 | if (file == INVALID_HANDLE_VALUE) 22 | { 23 | return -1; 24 | } 25 | 26 | if (SetFilePointer(file, length, NULL, FILE_BEGIN) == 0xFFFFFFFF || !SetEndOfFile(file)) 27 | { 28 | CloseHandle(file); 29 | return -1; 30 | } 31 | 32 | CloseHandle(file); 33 | return 0; 34 | } 35 | 36 | #endif 37 | 38 | #if defined(__SYMBIAN32__) 39 | int truncate(const char* path, long length) 40 | { 41 | // TODO: Implement for Symbian 42 | return -1; 43 | } 44 | #endif 45 | -------------------------------------------------------------------------------- /source/PortableTruncate.h: -------------------------------------------------------------------------------- 1 | 2 | #ifdef __cplusplus 3 | extern "C" { 4 | #endif 5 | 6 | 7 | #ifdef _WIN32 8 | #include "Common.h" 9 | 10 | BASEKIT_API int truncate(const char *path, long length); 11 | 12 | #else 13 | 14 | #include 15 | 16 | #endif 17 | 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | -------------------------------------------------------------------------------- /source/PortableUsleep.c: -------------------------------------------------------------------------------- 1 | int PortableUsleep_justHereToAvoidRanlibWarning(void) { return 0; } 2 | 3 | #ifdef WIN32 4 | #include 5 | 6 | int usleep(unsigned int us) 7 | { 8 | static LARGE_INTEGER freq; 9 | static int initted = 0; 10 | LARGE_INTEGER s, e, d; 11 | 12 | if (!initted) 13 | { 14 | QueryPerformanceFrequency(&freq); 15 | initted = 1; 16 | } 17 | 18 | QueryPerformanceCounter(&s); 19 | d.QuadPart = freq.QuadPart * ((double)us / 1000000.0); 20 | 21 | do 22 | { 23 | QueryPerformanceCounter(&e); 24 | } while (e.QuadPart - s.QuadPart < d.QuadPart); 25 | 26 | return 0; 27 | 28 | } 29 | 30 | #endif 31 | 32 | 33 | -------------------------------------------------------------------------------- /source/PortableUsleep.h: -------------------------------------------------------------------------------- 1 | 2 | #ifdef ON_WINDOWS 3 | #include 4 | #ifndef WIN32 5 | int usleep (unsigned int us); 6 | #endif 7 | #elif !defined(__CYGWIN__) 8 | #include 9 | #endif 10 | 11 | -------------------------------------------------------------------------------- /source/RandomGen.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef RANDOMGEN_DEFINED 4 | #define RANDOMGEN_DEFINED 1 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #include "Common.h" 11 | 12 | #define RANDOMGEN_N 624 13 | 14 | typedef struct 15 | { 16 | unsigned long mt[RANDOMGEN_N]; // the array for the state vector 17 | int mti; // mti==N+1 means mt[N] is not initialized 18 | double y2; // guassian 19 | int use_last; // guassian 20 | } RandomGen; 21 | 22 | BASEKIT_API RandomGen *RandomGen_new(void); 23 | BASEKIT_API void RandomGen_free(RandomGen *self); 24 | 25 | BASEKIT_API void RandomGen_setSeed(RandomGen *self, unsigned long seed); 26 | BASEKIT_API void RandomGen_chooseRandomSeed(RandomGen *self); 27 | 28 | // generates a random number on between 0.0 and 1.0 29 | BASEKIT_API double RandomGen_randomDouble(RandomGen *self); 30 | 31 | BASEKIT_API int RandomGen_randomInt(RandomGen *self); 32 | 33 | BASEKIT_API double RandomGen_gaussian(RandomGen *self, double mean, double standardDeviation); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | #endif 39 | -------------------------------------------------------------------------------- /source/Stack.c: -------------------------------------------------------------------------------- 1 | //metadoc Stack copyright Steve Dekorte 2002 2 | //metadoc Stack license BSD revised 3 | /*metadoc Stack description 4 | Notes: first element of items is always 0x0. 5 | */ 6 | 7 | #define STACK_C 8 | #include "Stack.h" 9 | #undef STACK_C 10 | #if !defined(_MSC_VER) 11 | #include 12 | #endif 13 | 14 | Stack *Stack_new(void) 15 | { 16 | // size is the number of pointers, including the starting NULL. 17 | int size = STACK_START_SIZE; 18 | Stack *self = (Stack *)io_calloc(1, sizeof(Stack)); 19 | self->items = (void **)io_calloc(1, size*sizeof(void *)); 20 | // memEnd points past the end of the items memory block. 21 | self->memEnd = self->items + size; 22 | self->top = self->items; 23 | //self->lastMark = self->items; 24 | return self; 25 | } 26 | 27 | void Stack_free(Stack *self) 28 | { 29 | io_free(self->items); 30 | io_free(self); 31 | } 32 | 33 | Stack *Stack_clone(const Stack *self) 34 | { 35 | Stack *s = (Stack *)cpalloc(self, sizeof(Stack)); 36 | 37 | ptrdiff_t nItems = self->top - self->items; 38 | ptrdiff_t size = nItems + 1; 39 | 40 | s->items = (void **)cpalloc(self->items, size*sizeof(void *)); 41 | s->memEnd = s->items + size; 42 | s->top = s->items + nItems; 43 | return s; 44 | } 45 | 46 | void Stack_copy_(Stack *self, const Stack *other) 47 | { 48 | ptrdiff_t nItems = self->top - self->items; 49 | ptrdiff_t size = nItems + 1; 50 | ptrdiff_t sizeInBytes = size*sizeof(void *); 51 | 52 | self->items = (void **)io_realloc(self->items, sizeInBytes); 53 | memcpy(self->items, other->items, sizeInBytes); 54 | self->memEnd = self->items + size; 55 | self->top = self->items + nItems; 56 | } 57 | 58 | 59 | // stack -------------------------------------------------- 60 | 61 | size_t Stack_memorySize(const Stack *self) 62 | { 63 | return sizeof(Stack) + (self->memEnd - self->items); 64 | } 65 | 66 | void Stack_compact(Stack *self) 67 | { 68 | int oldSize = (1 + self->top - self->items)*sizeof(void *); 69 | self->items = (void **)io_realloc(self->items, oldSize); 70 | } 71 | 72 | void Stack_resize(Stack *self) 73 | { 74 | int oldSize = (self->memEnd - self->items)*sizeof(void *); 75 | int newSize = oldSize*STACK_RESIZE_FACTOR; 76 | int i = self->top - self->items; 77 | self->items = (void **)io_realloc(self->items, newSize); 78 | self->top = self->items + i; 79 | self->memEnd = self->items + (newSize/sizeof(void *)); 80 | } 81 | 82 | // sizing ------------------------------------------------ 83 | 84 | void Stack_do_on_(const Stack *self, StackDoOnCallback *callback, void *target) 85 | { 86 | Stack *stack = Stack_newCopyWithNullMarks(self); 87 | int i; 88 | 89 | for(i = 0; i < Stack_count(stack) - 1; i ++) 90 | { 91 | void *v = Stack_at_(stack, i); 92 | if (v) (*callback)(target, v); 93 | } 94 | 95 | Stack_free(stack); 96 | } 97 | 98 | void Stack_makeMarksNull(Stack *self) 99 | { 100 | ptrdiff_t mark = self->lastMark; 101 | 102 | while (mark) 103 | { 104 | ptrdiff_t nextMark = (ptrdiff_t)self->items[mark]; 105 | self->items[mark] = NULL; 106 | mark = nextMark; 107 | } 108 | } 109 | 110 | Stack *Stack_newCopyWithNullMarks(const Stack *self) 111 | { 112 | Stack *newStack = Stack_clone(self); 113 | Stack_makeMarksNull(newStack); 114 | return newStack; 115 | } 116 | 117 | void Stack_popToMark_(Stack *self, intptr_t mark) 118 | { 119 | while (self->lastMark && self->lastMark != mark) 120 | { 121 | Stack_popMark(self); 122 | } 123 | 124 | if (self->lastMark == 0) 125 | { 126 | printf("Stack error: unable to find mark %p in %p\n", (void *)mark, (void *)self); 127 | exit(1); 128 | } 129 | 130 | Stack_popMark(self); 131 | } 132 | 133 | List *Stack_asList(const Stack *self) // slow 134 | { 135 | List *list = List_new(); 136 | Stack_do_on_(self, (StackDoOnCallback *)List_append_, list); 137 | return list; 138 | } 139 | -------------------------------------------------------------------------------- /source/Stack.h: -------------------------------------------------------------------------------- 1 | //metadoc Stack copyright Steve Dekorte 2002 2 | //metadoc Stack license BSD revised 3 | /*metadoc Stack description 4 | Stack - array of void pointers 5 | supports setting marks - when a mark is popped, 6 | all stack items above it are popped as well 7 | 8 | Designed to optimize push, pushMark and popMark 9 | at the expense of pop (since pop requires a mark check) 10 | */ 11 | 12 | #ifndef STACK_DEFINED 13 | #define STACK_DEFINED 1 14 | 15 | #include "Common.h" 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "List.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | #ifdef LOW_MEMORY_SYSTEM 27 | #define STACK_START_SIZE 512 28 | #define STACK_RESIZE_FACTOR 2 29 | #else 30 | #define STACK_START_SIZE 512 31 | #define STACK_RESIZE_FACTOR 2 32 | #endif 33 | 34 | typedef void (StackDoCallback)(void *); 35 | typedef void (StackDoOnCallback)(void *, void *); 36 | 37 | //#define STACK_POP_CALLBACK 38 | 39 | #ifdef STACK_POP_CALLBACK 40 | typedef void (StackPopCallback)(void *); 41 | #endif 42 | 43 | typedef struct 44 | { 45 | void **items; 46 | void **memEnd; 47 | void **top; 48 | intptr_t lastMark; 49 | 50 | #ifdef STACK_POP_CALLBACK 51 | StackPopCallback *popCallback; 52 | #endif 53 | } Stack; 54 | 55 | #define Stack_popCallback_(self, callback) self->popCallback = callback; 56 | 57 | BASEKIT_API Stack *Stack_new(void); 58 | BASEKIT_API void Stack_free(Stack *self); 59 | BASEKIT_API Stack *Stack_clone(const Stack *self); 60 | BASEKIT_API void Stack_copy_(Stack *self, const Stack *other); 61 | 62 | BASEKIT_API size_t Stack_memorySize(const Stack *self); 63 | BASEKIT_API void Stack_compact(Stack *self); 64 | 65 | BASEKIT_API void Stack_resize(Stack *self); 66 | 67 | BASEKIT_API void Stack_popToMark_(Stack *self, intptr_t mark); 68 | 69 | // not high performance 70 | 71 | BASEKIT_API void Stack_makeMarksNull(Stack *self); 72 | BASEKIT_API Stack *Stack_newCopyWithNullMarks(const Stack *self); 73 | BASEKIT_API void Stack_do_on_(const Stack *self, StackDoOnCallback *callback, void *target); 74 | 75 | BASEKIT_API List *Stack_asList(const Stack *self); 76 | 77 | #include "Stack_inline.h" 78 | 79 | #ifdef __cplusplus 80 | } 81 | #endif 82 | #endif 83 | -------------------------------------------------------------------------------- /source/Stack_inline.h: -------------------------------------------------------------------------------- 1 | //metadoc Stack copyright Steve Dekorte 2002 2 | //metadoc Stack license BSD revised 3 | /*metadoc Stack description 4 | Stack - array of void pointers 5 | supports setting marks - when a mark is popped, 6 | all stack items above it are popped as well 7 | */ 8 | 9 | #ifdef STACK_C 10 | #define IO_IN_C_FILE 11 | #endif 12 | #include "Common_inline.h" 13 | #ifdef IO_DECLARE_INLINES 14 | 15 | IOINLINE void Stack_do_(const Stack *self, StackDoCallback *callback) 16 | { 17 | void **itemP = self->top; 18 | intptr_t mark = self->lastMark; 19 | 20 | while (itemP > self->items) 21 | { 22 | if (itemP - self->items == mark) 23 | { 24 | mark = (intptr_t)(*itemP); 25 | } 26 | else 27 | { 28 | (*callback)(*itemP); 29 | } 30 | 31 | itemP --; 32 | } 33 | } 34 | 35 | IOINLINE void Stack_doUntilMark_(const Stack *self, StackDoCallback *callback) 36 | { 37 | void **itemP = self->top; 38 | intptr_t mark = self->lastMark; 39 | 40 | while (itemP > self->items) 41 | { 42 | if (itemP - self->items == mark) 43 | { 44 | return; 45 | } 46 | else 47 | { 48 | (*callback)(*itemP); 49 | } 50 | 51 | itemP --; 52 | } 53 | } 54 | 55 | IOINLINE void Stack_clear(Stack *self) 56 | { 57 | self->top = self->items; 58 | self->lastMark = 0; 59 | } 60 | 61 | IOINLINE size_t Stack_totalSize(const Stack *self) 62 | { 63 | return (self->top - self->items); 64 | } 65 | 66 | IOINLINE int Stack_count(const Stack *self) 67 | { 68 | return (self->top - self->items); 69 | } 70 | 71 | IOINLINE void Stack_push_(Stack *self, void *item) 72 | { 73 | self->top ++; 74 | 75 | if (self->top == self->memEnd) 76 | { 77 | Stack_resize(self); 78 | } 79 | 80 | *(self->top) = item; 81 | } 82 | 83 | IOINLINE void Stack_pushMark(Stack *self) 84 | { 85 | Stack_push_(self, (void *)self->lastMark); 86 | self->lastMark = self->top - self->items; 87 | } 88 | 89 | IOINLINE intptr_t Stack_pushMarkPoint(Stack *self) 90 | { 91 | Stack_push_(self, (void *)self->lastMark); 92 | self->lastMark = self->top - self->items; 93 | return self->lastMark; 94 | } 95 | 96 | IOINLINE void *Stack_pop(Stack *self) 97 | { 98 | void *top = *(self->top); 99 | 100 | if (self->items != self->top) 101 | { 102 | #ifdef STACK_POP_CALLBACK 103 | if(self->popCallback) self->popCallback(*(self->top)); 104 | #endif 105 | self->top --; 106 | } 107 | 108 | return top; 109 | } 110 | 111 | IOINLINE void Stack_popMark(Stack *self) 112 | { 113 | #ifdef STACK_POP_CALLBACK 114 | if(self->popCallback) Stack_doUntilMark_(self, self->popCallback); 115 | #endif 116 | 117 | self->top = self->items + self->lastMark - 1; 118 | 119 | if (self->lastMark) 120 | { 121 | self->lastMark = (intptr_t)(self->items[self->lastMark]); 122 | } 123 | } 124 | 125 | IOINLINE int Stack_popMarkPoint_(Stack *self, intptr_t mark) 126 | { 127 | while (self->lastMark && self->lastMark != mark) 128 | { 129 | Stack_popMark(self); 130 | } 131 | 132 | if (self->lastMark != mark) 133 | { 134 | return 0; 135 | } 136 | 137 | Stack_popMark(self); 138 | return 1; 139 | } 140 | 141 | IOINLINE void Stack_clearTop(Stack *self) 142 | { 143 | Stack_popMark(self); 144 | Stack_pushMark(self); 145 | //self->top = self->items + self->lastMark; 146 | } 147 | 148 | IOINLINE void *Stack_top(const Stack *self) 149 | { 150 | return *(self->top); 151 | } 152 | 153 | IOINLINE void *Stack_at_(const Stack *self, int i) 154 | { 155 | return self->items[i + 1]; 156 | } 157 | 158 | 159 | 160 | #undef IO_IN_C_FILE 161 | #endif 162 | 163 | -------------------------------------------------------------------------------- /source/UArray_character.c: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | #include "UArray.h" 7 | #include 8 | #include 9 | 10 | // set 11 | 12 | #define UARRAY_IOP(OP) \ 13 | void UArray_ ## OP (UArray *self) { UARRAY_FOREACHASSIGN(self, i, v, OP((int)v)); } 14 | 15 | UARRAY_IOP(isalnum); 16 | UARRAY_IOP(isalpha); 17 | UARRAY_IOP(iscntrl); 18 | UARRAY_IOP(isdigit); 19 | UARRAY_IOP(isgraph); 20 | UARRAY_IOP(islower); 21 | UARRAY_IOP(isprint); 22 | UARRAY_IOP(ispunct); 23 | UARRAY_IOP(isspace); 24 | UARRAY_IOP(isupper); 25 | UARRAY_IOP(isxdigit); 26 | 27 | UARRAY_IOP(tolower); 28 | UARRAY_IOP(toupper); 29 | 30 | BASEKIT_API int UArray_isLowercase(UArray *self) 31 | { 32 | UARRAY_INTFOREACH(self, i, v, if(v != tolower(v)) return 0); 33 | return 1; 34 | } 35 | 36 | BASEKIT_API int UArray_isUppercase(UArray *self) 37 | { 38 | UARRAY_INTFOREACH(self, i, v, if(v != toupper(v)) return 0); 39 | return 1; 40 | } 41 | -------------------------------------------------------------------------------- /source/UArray_character.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | BASEKIT_API void UArray_isalnum(UArray *self); 7 | BASEKIT_API void UArray_isalpha(UArray *self); 8 | BASEKIT_API void UArray_iscntrl(UArray *self); 9 | BASEKIT_API void UArray_isdigit(UArray *self); 10 | BASEKIT_API void UArray_isgraph(UArray *self); 11 | BASEKIT_API void UArray_islower(UArray *self); 12 | BASEKIT_API void UArray_isprint(UArray *self); 13 | BASEKIT_API void UArray_ispunct(UArray *self); 14 | BASEKIT_API void UArray_isspace(UArray *self); 15 | BASEKIT_API void UArray_isupper(UArray *self); 16 | BASEKIT_API void UArray_isxdigit(UArray *self); 17 | BASEKIT_API void UArray_tolower(UArray *self); 18 | BASEKIT_API void UArray_toupper(UArray *self); 19 | 20 | BASEKIT_API int UArray_isLowercase(UArray *self); 21 | BASEKIT_API int UArray_isUppercase(UArray *self); 22 | -------------------------------------------------------------------------------- /source/UArray_format.c: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | #include "UArray.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | UArray *UArray_newWithFormat_(const char *format, ...) 13 | { 14 | UArray *self; 15 | va_list ap; 16 | va_start(ap, format); 17 | self = UArray_newWithVargs_(format, ap); 18 | va_end(ap); 19 | return self; 20 | } 21 | 22 | UArray *UArray_newWithVargs_(const char *format, va_list ap) 23 | { 24 | UArray *self = UArray_new(); 25 | UArray_fromVargs_(self, format,ap); 26 | return self; 27 | } 28 | 29 | UArray *UArray_fromFormat_(UArray *self, const char *format, ...) 30 | { 31 | va_list ap; 32 | va_start(ap, format); 33 | UArray_fromVargs_(self, format, ap); 34 | va_end(ap); 35 | return self; 36 | } 37 | 38 | void UArray_fromVargs_(UArray *self, const char *format, va_list ap) 39 | { 40 | while (*format) 41 | { 42 | if (*format == '%') 43 | { 44 | format ++; 45 | 46 | if (*format == 's') 47 | { 48 | char *s = va_arg(ap, char *); 49 | if (!s) { printf("UArray_fromVargs_ missing param"); return; } 50 | UArray_appendCString_(self, s); 51 | } 52 | else if (*format == 'i' || *format == 'd') 53 | { 54 | int i = va_arg(ap, int); 55 | char s[100]; 56 | 57 | snprintf(s, 100, "%i", i); 58 | UArray_appendCString_(self, s); 59 | } 60 | else if (*format == 'f') 61 | { 62 | double d = va_arg(ap, double); 63 | char s[100]; 64 | 65 | snprintf(s, 100, "%f", d); 66 | UArray_appendCString_(self, s); 67 | } 68 | else if (*format == 'p') 69 | { 70 | void *p = va_arg(ap, void *); 71 | char s[100]; 72 | 73 | snprintf(s, 100, "%p", p); 74 | UArray_appendCString_(self, s); 75 | } 76 | // new format command for a given number adding spaces 77 | else if (*format == '#') 78 | { 79 | int n, i = va_arg(ap, int); 80 | char *s = " "; 81 | 82 | for (n = 0; n < i; n ++) 83 | { 84 | UArray_appendCString_(self, s); 85 | } 86 | } 87 | } 88 | else 89 | { 90 | char s[2]; 91 | 92 | snprintf(s, 2, "%c", *format); 93 | UArray_appendCString_(self, s); 94 | } 95 | 96 | format ++; 97 | } 98 | } 99 | 100 | UArray *UArray_asNewHexStringUArray(UArray *self) 101 | { 102 | size_t i, newSize = self->size * 2; 103 | UArray *ba = UArray_new(); 104 | UArray_setSize_(ba, newSize); 105 | 106 | for(i = 0; i < self->size; i ++) 107 | { 108 | int v = UArray_longAt_(self, i); 109 | char *s = (char *)(ba->data + i * 2); 110 | 111 | if (v < 16) 112 | { 113 | snprintf(s, newSize, "0%x", (int)v); 114 | } 115 | else 116 | { 117 | snprintf(s, newSize, "%x", (int)v); 118 | } 119 | } 120 | 121 | return ba; 122 | } 123 | -------------------------------------------------------------------------------- /source/UArray_format.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | BASEKIT_API UArray *UArray_newWithFormat_(const char *format, ...); 7 | BASEKIT_API UArray *UArray_newWithVargs_(const char *format, va_list ap); 8 | BASEKIT_API UArray *UArray_fromFormat_(UArray *self, const char *format, ...); 9 | BASEKIT_API void UArray_fromVargs_(UArray *self, const char *format, va_list ap); 10 | 11 | BASEKIT_API UArray *UArray_asNewHexStringUArray(UArray *self); 12 | -------------------------------------------------------------------------------- /source/UArray_math.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | // set 7 | 8 | BASEKIT_API void UArray_clear(UArray *self); 9 | BASEKIT_API void UArray_setItemsToLong_(UArray *self, long x); 10 | BASEKIT_API void UArray_setItemsToDouble_(UArray *self, double x); 11 | BASEKIT_API void UArray_rangeFill(UArray *self); 12 | BASEKIT_API void UArray_negate(const UArray *self); 13 | 14 | // basic vector math 15 | 16 | BASEKIT_API void UArray_add_(UArray *self, const UArray *other); 17 | BASEKIT_API void UArray_subtract_(UArray *self, const UArray *other); 18 | BASEKIT_API void UArray_multiply_(UArray *self, const UArray *other); 19 | BASEKIT_API void UArray_divide_(UArray *self, const UArray *other); 20 | BASEKIT_API double UArray_dotProduct_(const UArray *self, const UArray *other); 21 | 22 | // basic scalar math 23 | 24 | BASEKIT_API void UArray_addScalarDouble_(UArray *self, double v); 25 | BASEKIT_API void UArray_subtractScalarDouble_(UArray *self, double v); 26 | BASEKIT_API void UArray_multiplyScalarDouble_(UArray *self, double v); 27 | BASEKIT_API void UArray_divideScalarDouble_(UArray *self, double v); 28 | 29 | // bitwise logic 30 | 31 | BASEKIT_API void UArray_bitwiseOr_(UArray *self, const UArray *other); 32 | BASEKIT_API void UArray_bitwiseAnd_(UArray *self, const UArray *other); 33 | BASEKIT_API void UArray_bitwiseXor_(UArray *self, const UArray *other); 34 | BASEKIT_API void UArray_bitwiseNot(UArray *self); 35 | 36 | // bitwise ops 37 | 38 | BASEKIT_API void UArray_setAllBitsTo_(UArray *self, uint8_t aBool); 39 | BASEKIT_API uint8_t UArray_byteAt_(UArray *self, size_t i); 40 | BASEKIT_API int UArray_bitAt_(UArray *self, size_t i); 41 | BASEKIT_API void UArray_setBit_at_(UArray *self, int b, size_t i); 42 | BASEKIT_API UArray * UArray_asBits(const UArray *self); 43 | BASEKIT_API size_t UArray_bitCount(UArray *self); 44 | 45 | // boolean logic 46 | 47 | BASEKIT_API void UArray_logicalOr_(UArray *self, const UArray *other); 48 | BASEKIT_API void UArray_logicalAnd_(UArray *self, const UArray *other); 49 | 50 | // trigonometry 51 | 52 | BASEKIT_API void UArray_sin(UArray *self); 53 | BASEKIT_API void UArray_cos(UArray *self); 54 | BASEKIT_API void UArray_tan(UArray *self); 55 | 56 | BASEKIT_API void UArray_asin(UArray *self); 57 | BASEKIT_API void UArray_acos(UArray *self); 58 | BASEKIT_API void UArray_atan(UArray *self); 59 | 60 | //void UArray_atan2(UArray *self, const UArray *other); 61 | 62 | BASEKIT_API void UArray_sinh(UArray *self); 63 | BASEKIT_API void UArray_cosh(UArray *self); 64 | BASEKIT_API void UArray_tanh(UArray *self); 65 | 66 | BASEKIT_API void UArray_exp(UArray *self); 67 | BASEKIT_API void UArray_log(UArray *self); 68 | BASEKIT_API void UArray_log10(UArray *self); 69 | 70 | //void UArray_pow(UArray *self, const UArray *other); 71 | 72 | BASEKIT_API void UArray_sqrt(UArray *self); 73 | BASEKIT_API void UArray_ceil(UArray *self); 74 | BASEKIT_API void UArray_floor(UArray *self); 75 | BASEKIT_API void UArray_abs(UArray *self); 76 | BASEKIT_API void UArray_round(UArray *self); 77 | 78 | //void UArray_ldexp(UArray *self, const UArray *other); 79 | //void UArray_fmod(UArray *self, const UArray *other); 80 | 81 | BASEKIT_API void UArray_square(UArray *self); 82 | BASEKIT_API void UArray_normalize(UArray *self); 83 | 84 | BASEKIT_API void UArray_crossProduct_(UArray *self, const UArray *other); 85 | BASEKIT_API double UArray_distanceTo_(const UArray *self, const UArray *other); 86 | 87 | // extras 88 | 89 | BASEKIT_API double UArray_sumAsDouble(const UArray *self); 90 | BASEKIT_API double UArray_productAsDouble(const UArray *self); 91 | BASEKIT_API double UArray_arithmeticMeanAsDouble(const UArray *self); 92 | BASEKIT_API double UArray_arithmeticMeanSquareAsDouble(const UArray *self); 93 | BASEKIT_API double UArray_maxAsDouble(const UArray *self); 94 | BASEKIT_API double UArray_minAsDouble(const UArray *self); 95 | BASEKIT_API void UArray_Max(UArray *self, const UArray *other); 96 | BASEKIT_API void UArray_Min(UArray *self, const UArray *other); 97 | 98 | // hash 99 | 100 | BASEKIT_API void UArray_changed(UArray *self); 101 | BASEKIT_API uintptr_t UArray_calcHash(UArray *self); 102 | BASEKIT_API uintptr_t UArray_evenHash(UArray *self); 103 | BASEKIT_API uintptr_t UArray_oddHash(UArray *self); 104 | #define UArray_hash UArray_evenHash 105 | BASEKIT_API int UArray_equalsWithHashCheck_(UArray *self, UArray *other); 106 | 107 | // indexes 108 | 109 | BASEKIT_API void UArray_duplicateIndexes(UArray *self); 110 | BASEKIT_API void UArray_removeOddIndexes(UArray *self); 111 | BASEKIT_API void UArray_removeEvenIndexes(UArray *self); 112 | 113 | BASEKIT_API void UArray_reverseItemByteOrders(UArray *self); 114 | 115 | BASEKIT_API void UArray_addEqualsOffsetXScaleYScale(UArray *self, UArray *other, float offset, float xscale, float yscale); 116 | 117 | -------------------------------------------------------------------------------- /source/UArray_path.c: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | #include "UArray.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | void UArray_appendPath_(UArray *self, const UArray *path) 13 | { 14 | const UArray sep = UArray_stackAllocedWithCString_(OS_PATH_SEPARATOR); 15 | 16 | int selfEndsWithSep = IS_PATH_SEPERATOR(UArray_lastLong(self)); 17 | int pathStartsWithSep = IS_PATH_SEPERATOR(UArray_firstLong(path)); 18 | 19 | if (!selfEndsWithSep && !pathStartsWithSep) 20 | { 21 | if(self->size != 0) UArray_append_(self, &sep); 22 | UArray_append_(self, path); 23 | } 24 | else if (selfEndsWithSep && pathStartsWithSep) 25 | { 26 | const UArray pathPart = UArray_stackRange(path, 1, path->size - 1); 27 | UArray_append_(self, &pathPart); 28 | } 29 | else 30 | { 31 | UArray_append_(self, path); 32 | } 33 | } 34 | 35 | void UArray_removeLastPathComponent(UArray *self) 36 | { 37 | long pos = UArray_findLastPathComponent(self); 38 | if (pos) pos --; 39 | UArray_setSize_(self, pos); 40 | } 41 | 42 | void UArray_clipBeforeLastPathComponent(UArray *self) 43 | { 44 | long pos = UArray_findLastPathComponent(self); 45 | 46 | if (pos != -1) 47 | { 48 | UArray_removeRange(self, 0, pos); 49 | } 50 | } 51 | 52 | long UArray_findLastPathComponent(const UArray *self) 53 | { 54 | if (self->size) 55 | { 56 | UArray seps = UArray_stackAllocedWithCString_(IO_PATH_SEPARATORS); 57 | UArray s = UArray_stackRange(self, 0, self->size); 58 | long pos = 0; 59 | 60 | while (s.size && (pos = UArray_rFindAnyValue_(&s, &seps)) == s.size - 1) 61 | { 62 | s.size = pos; 63 | } 64 | 65 | if (pos == -1) { pos = 0; } else { pos ++; } 66 | return pos; 67 | } 68 | 69 | return 0; 70 | } 71 | 72 | UArray *UArray_lastPathComponent(const UArray *self) 73 | { 74 | long pos = UArray_findLastPathComponent(self); 75 | return UArray_range(self, pos, self->size - pos); 76 | } 77 | 78 | long UArray_findPathExtension(UArray *self) 79 | { 80 | UArray dot = UArray_stackAllocedWithCString_(IO_PATH_SEPARATOR_DOT); 81 | return UArray_rFind_(self, &dot); 82 | } 83 | 84 | void UArray_removePathExtension(UArray *self) 85 | { 86 | long pos = UArray_findPathExtension(self); 87 | 88 | if (pos != -1) 89 | { 90 | UArray_setSize_(self, pos); 91 | } 92 | } 93 | 94 | UArray *UArray_pathExtension(UArray *self) 95 | { 96 | long pos = UArray_findPathExtension(self); 97 | 98 | if (pos == -1 || pos == self->size - 1) 99 | { 100 | return UArray_newWithCString_copy_("", 1); 101 | } 102 | 103 | return UArray_range(self, pos + 1, self->size - pos - 1); 104 | } 105 | 106 | UArray *UArray_fileName(UArray *self) 107 | { 108 | long extPos = UArray_findLastPathComponent(self); 109 | long dotPos = UArray_findPathExtension(self); 110 | 111 | //if (extPos == -1) { extPos = 0; } else { extPos ++; } 112 | if (dotPos == -1) dotPos = self->size; 113 | 114 | return UArray_range(self, extPos, dotPos - extPos); 115 | } 116 | 117 | // to/from os path - always returns a copy 118 | 119 | int UArray_OSPathSeparatorIsUnixSeparator(void) 120 | { 121 | return strcmp(OS_PATH_SEPARATOR, "/") == 0; 122 | } 123 | 124 | UArray *UArray_asOSPath(UArray *self) 125 | { 126 | UArray *a = UArray_clone(self); 127 | UArray_replaceCString_withCString_(a, IO_PATH_SEPARATOR, OS_PATH_SEPARATOR); 128 | return a; 129 | } 130 | 131 | UArray *UArray_asUnixPath(UArray *self) 132 | { 133 | UArray *a = UArray_clone(self); 134 | UArray_replaceCString_withCString_(a, OS_PATH_SEPARATOR, IO_PATH_SEPARATOR); 135 | return a; 136 | } 137 | 138 | -------------------------------------------------------------------------------- /source/UArray_path.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | // internally, Io always uses a forward slash "/" for path separators, 7 | // but on Windows, back slashes are also tolerated as path separators. 8 | #if defined(DOS) || defined(ON_WINDOWS) 9 | #define OS_PATH_SEPARATOR "\\" 10 | #define IO_PATH_SEPARATORS "\\/" 11 | #else 12 | #define OS_PATH_SEPARATOR "/" 13 | #define IO_PATH_SEPARATORS "/" 14 | #endif 15 | 16 | #define IO_PATH_SEPARATOR "/" 17 | #define IO_PATH_SEPARATOR_DOT "." 18 | 19 | 20 | #ifdef ON_WINDOWS 21 | #define IS_PATH_SEPERATOR(ch) ((ch == '/') || (ch == '\\')) 22 | #else 23 | #define IS_PATH_SEPERATOR(ch) (ch == '/') 24 | #endif 25 | 26 | 27 | BASEKIT_API void UArray_appendPath_(UArray *self, const UArray *path); 28 | 29 | // last component 30 | 31 | BASEKIT_API void UArray_removeLastPathComponent(UArray *self); 32 | BASEKIT_API void UArray_clipBeforeLastPathComponent(UArray *self); 33 | BASEKIT_API long UArray_findLastPathComponent(const UArray *self); 34 | BASEKIT_API UArray *UArray_lastPathComponent(const UArray *self); 35 | 36 | // extension 37 | 38 | BASEKIT_API long UArray_findPathExtension(UArray *self); 39 | BASEKIT_API void UArray_removePathExtension(UArray *self); 40 | BASEKIT_API UArray *UArray_pathExtension(UArray *self); 41 | 42 | // fileName 43 | 44 | BASEKIT_API UArray *UArray_fileName(UArray *self); 45 | 46 | // to/from os path - always returns a copy 47 | 48 | BASEKIT_API int UArray_OSPathSeparatorIsUnixSeparator(void); 49 | BASEKIT_API UArray *UArray_asOSPath(UArray *self); 50 | BASEKIT_API UArray *UArray_asUnixPath(UArray *self); 51 | 52 | -------------------------------------------------------------------------------- /source/UArray_stream.c: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | #include "UArray.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | // read ------------------------------------------------------ 13 | 14 | size_t UArray_fread_(UArray *self, FILE *fp) 15 | { 16 | size_t itemsRead = fread(self->data, self->itemSize, self->size, fp); 17 | UArray_setSize_(self, itemsRead); 18 | return itemsRead; 19 | } 20 | 21 | long UArray_readFromCStream_(UArray *self, FILE *fp) 22 | { 23 | long totalItemsRead = 0; 24 | long itemsPerBuffer = 4096 / self->itemSize; 25 | UArray *buffer = UArray_new(); 26 | UArray_setItemType_(buffer, self->itemType); 27 | UArray_setSize_(buffer, itemsPerBuffer); 28 | 29 | if (!fp) { perror("UArray_readFromCStream_"); return -1; } 30 | 31 | while(!feof(fp) && !ferror(fp)) 32 | { 33 | size_t itemsRead; 34 | UArray_setSize_(buffer, itemsPerBuffer); 35 | itemsRead = UArray_fread_(buffer, fp); 36 | 37 | totalItemsRead += itemsRead; 38 | UArray_append_(self, buffer); 39 | if (itemsRead != itemsPerBuffer) break; 40 | } 41 | 42 | if (ferror(fp)) { perror("UArray_readFromCStream_"); return -1; } 43 | 44 | UArray_free(buffer); 45 | return totalItemsRead; 46 | } 47 | 48 | long UArray_readNumberOfItems_fromCStream_(UArray *self, size_t size, FILE *stream) 49 | { 50 | size_t itemsRead; 51 | UArray *buffer = UArray_new(); 52 | UArray_setItemType_(buffer, self->itemType); 53 | UArray_setSize_(buffer, size); 54 | 55 | itemsRead = UArray_fread_(buffer, stream); 56 | UArray_append_(self, buffer); 57 | 58 | UArray_free(buffer); 59 | return itemsRead; 60 | } 61 | 62 | long UArray_readFromFilePath_(UArray *self, const UArray *path) 63 | { 64 | FILE *stream; 65 | long itemsRead; 66 | UArray *sysPath = (UArray_itemSize(path) == 1) ? (UArray *)path : UArray_asUTF8(path); 67 | const char *p = UArray_asCString(sysPath); 68 | 69 | //printf("UArray_readFromFilePath_(\"%s\")\n", p); 70 | 71 | stream = fopen(p, "rb"); 72 | if (!stream) return -1; 73 | itemsRead = UArray_readFromCStream_(self, stream); 74 | fclose(stream); 75 | 76 | if(sysPath != path) UArray_free(sysPath); 77 | return itemsRead; 78 | } 79 | 80 | 81 | #define CHUNK_SIZE 4096 82 | 83 | int UArray_readLineFromCStream_(UArray *self, FILE *stream) 84 | { 85 | int readSomething = 0; 86 | 87 | if(self->itemSize == 1) 88 | { 89 | char *s = (char *)io_calloc(1, CHUNK_SIZE); 90 | 91 | while (fgets(s, CHUNK_SIZE, stream) != NULL) 92 | { 93 | char *eol1 = strchr(s, '\n'); 94 | char *eol2 = strchr(s, '\r'); 95 | 96 | readSomething = 1; 97 | 98 | if (eol1) { *eol1 = 0; } // remove the \n return character 99 | if (eol2) { *eol2 = 0; } // remove the \r return character 100 | 101 | if (*s) 102 | { 103 | UArray_appendCString_(self, s); 104 | } 105 | 106 | if (eol1 || eol2) 107 | { 108 | break; 109 | } 110 | } 111 | 112 | io_free(s); 113 | } 114 | 115 | return readSomething; 116 | } 117 | 118 | // write ------------------------------------------------------ 119 | 120 | size_t UArray_fwrite_(const UArray *self, size_t size, FILE *fp) 121 | { 122 | return fwrite(self->data, 1, self->itemSize * size, fp); 123 | } 124 | 125 | long UArray_writeToCStream_(const UArray *self, FILE *stream) 126 | { 127 | size_t totalItemsRead = UArray_fwrite_(self, self->size, stream); 128 | if (ferror(stream)) { perror("UArray_readFromCStream_"); return -1; } 129 | return totalItemsRead; 130 | } 131 | 132 | long UArray_writeToFilePath_(const UArray *self, const UArray *path) 133 | { 134 | UArray *sysPath = (UArray_itemSize(path) == 1) ? (UArray *)path : UArray_asUTF8(path); 135 | FILE *fp = fopen(UArray_asCString(sysPath), "w"); 136 | long itemsWritten = -1; 137 | 138 | if (fp) 139 | { 140 | itemsWritten = UArray_writeToCStream_(self, fp); 141 | fclose(fp); 142 | } 143 | 144 | return itemsWritten; 145 | } 146 | 147 | -------------------------------------------------------------------------------- /source/UArray_stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | // these return item read/written count or -1 on error 7 | 8 | // read 9 | 10 | BASEKIT_API size_t UArray_fread_(UArray *self, FILE *fp); 11 | BASEKIT_API long UArray_readFromCStream_(UArray *self, FILE *stream); 12 | BASEKIT_API long UArray_readFromFilePath_(UArray *self, const UArray *path); 13 | BASEKIT_API long UArray_readNumberOfItems_fromCStream_(UArray *self, size_t size, FILE *stream); 14 | BASEKIT_API int UArray_readLineFromCStream_(UArray *self, FILE *stream); 15 | 16 | // write 17 | 18 | BASEKIT_API size_t UArray_fwrite_(const UArray *self, size_t size, FILE *stream); 19 | BASEKIT_API long UArray_writeToCStream_(const UArray *self, FILE *stream); 20 | BASEKIT_API long UArray_writeToFilePath_(const UArray *self, const UArray *path); 21 | -------------------------------------------------------------------------------- /source/UArray_string.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | /* 7 | copyright: Steve Dekorte, 2006. All rights reserved. 8 | license: See _BSDLicense.txt. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | BASEKIT_API void UArray_append_(UArray *self, const UArray *other); 17 | BASEKIT_API void UArray_appendCString_(UArray *self, const char *s); 18 | BASEKIT_API void UArray_prepend_(UArray *self, const UArray *other); 19 | 20 | BASEKIT_API int UArray_equalsAnyCase_(const UArray *self, const UArray *other); 21 | BASEKIT_API void UArray_replace_with_(UArray *self, const UArray *a1, const UArray *a2); 22 | BASEKIT_API void UArray_replaceAnyCase_with_(UArray *self, const UArray *a1, const UArray *a2); 23 | BASEKIT_API void UArray_replaceCString_withCString_(UArray *self, const char *s1, const char *s2); 24 | BASEKIT_API void UArray_remove_(UArray *self, const UArray *a1); 25 | BASEKIT_API void UArray_removeAnyCase_(UArray *self, const UArray *a1); 26 | 27 | // clipping 28 | 29 | BASEKIT_API int UArray_clipBefore_(UArray *self, const UArray *other); 30 | BASEKIT_API int UArray_clipBeforeEndOf_(UArray *self, const UArray *other); 31 | BASEKIT_API int UArray_clipAfter_(UArray *self, const UArray *other); 32 | BASEKIT_API int UArray_clipAfterStartOf_(UArray *self, const UArray *other); 33 | 34 | // strip 35 | 36 | BASEKIT_API void UArray_lstrip_(UArray *self, const UArray *other); 37 | BASEKIT_API void UArray_rstrip_(UArray *self, const UArray *other); 38 | BASEKIT_API void UArray_strip_(UArray *self, const UArray *other); 39 | 40 | // swap 41 | 42 | BASEKIT_API void UArray_swapIndex_withIndex_(UArray *self, size_t i, size_t j); 43 | 44 | // reverse 45 | 46 | BASEKIT_API void UArray_reverse(UArray *self); 47 | 48 | //BASEKIT_API size_t UArray_matchingPrefixSizeWith_(const UArray *self, const UArray *other); 49 | 50 | // split 51 | 52 | BASEKIT_API PtrUArray *UArray_split_(const UArray *self, const PtrUArray *delims); 53 | BASEKIT_API size_t UArray_splitCount_(const UArray *self, const PtrUArray *delims); 54 | 55 | // find 56 | 57 | BASEKIT_API int UArray_beginsWith_(UArray *self, const UArray *other); 58 | BASEKIT_API int UArray_endsWith_(UArray *self, const UArray *other); 59 | 60 | // escape and quote 61 | 62 | BASEKIT_API void UArray_swapWith_(UArray *self, UArray *other); 63 | 64 | BASEKIT_API void UArray_escape(UArray *self); 65 | BASEKIT_API void UArray_unescape(UArray *self); 66 | 67 | BASEKIT_API void UArray_quote(UArray *self); 68 | BASEKIT_API void UArray_unquote(UArray *self); 69 | 70 | BASEKIT_API void UArray_translate(UArray *self, UArray *fromChars, UArray *toChars); 71 | BASEKIT_API size_t UArray_count_(const UArray *self, const UArray *other); 72 | 73 | // encoding 74 | 75 | BASEKIT_API UArray* UArray_asBase64(const UArray *self); 76 | BASEKIT_API UArray* UArray_fromBase64(const UArray *self); 77 | -------------------------------------------------------------------------------- /source/UArray_utf.c: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | #include "UArray.h" 7 | #include "utf_convert.h" 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "utf8.h" 13 | #include 14 | 15 | int UArray_MachineIsLittleEndian(void) 16 | { 17 | unsigned int i = 0x1; 18 | return ((unsigned char *)(&i))[0] == 1; 19 | } 20 | 21 | /* 22 | int strlenUTF8(char *s) 23 | { 24 | int i = 0; 25 | int len = 0; 26 | 27 | while (s[i]) 28 | { 29 | if ((s[i] & 0xc0) != 0x80) 30 | { 31 | len ++; 32 | } 33 | 34 | i ++; 35 | } 36 | 37 | return len; 38 | } 39 | */ 40 | 41 | static int UArray_SizeOfUTF8Char(const uint8_t *s) 42 | { 43 | uint8_t c = *s; 44 | 45 | if (c & 0x80) 46 | { 47 | if((c & 0xE0) == 0xC0) return 2; 48 | if((c & 0xF0) == 0xE0) return 3; 49 | if((c & 0xF8) == 0xF0) return 4; 50 | if((c & 0xFC) == 0xF8) return 5; 51 | if((c & 0xFE) == 0xFC) return 6; 52 | return -1; 53 | } 54 | 55 | return 1; 56 | } 57 | 58 | int UArray_maxCharSize(const UArray *self) 59 | { 60 | if (self->encoding == CENCODING_UTF8) 61 | { 62 | int maxCharSize = 1; 63 | size_t i = 0; 64 | 65 | while (i < self->size) 66 | { 67 | int charSize = UArray_SizeOfUTF8Char(self->data + i); 68 | if (charSize > maxCharSize) maxCharSize = charSize; 69 | if (charSize == -1) return -1; 70 | i += charSize; 71 | } 72 | 73 | return maxCharSize; 74 | } 75 | 76 | return self->itemSize; 77 | } 78 | 79 | size_t UArray_numberOfCharacters(const UArray *self) 80 | { 81 | if (self->encoding == CENCODING_UTF8) 82 | { 83 | size_t numChars = 0; 84 | size_t i = 0; 85 | 86 | while (i < self->size) 87 | { 88 | int charSize = UArray_SizeOfUTF8Char(self->data + i); 89 | if (charSize == -1) return 0; 90 | numChars ++; 91 | i += charSize; 92 | } 93 | 94 | return numChars; 95 | } 96 | 97 | return self->size; 98 | } 99 | 100 | int UArray_convertToFixedSizeType(UArray *self) 101 | { 102 | if (self->encoding == CENCODING_UTF8) 103 | { 104 | int maxCharSize = UArray_maxCharSize(self); 105 | 106 | if (maxCharSize == 1) 107 | { 108 | self->encoding = CENCODING_ASCII; 109 | } 110 | else if(maxCharSize == 2) 111 | { 112 | UArray_convertToUCS2(self); 113 | } 114 | else 115 | { 116 | UArray_convertToUCS4(self); 117 | } 118 | 119 | return 1; 120 | } 121 | 122 | return 0; 123 | } 124 | 125 | int UArray_isMultibyte(const UArray *self) 126 | { 127 | if (self->encoding == CENCODING_UTF8) 128 | { 129 | size_t i, max = UArray_sizeInBytes(self); 130 | const uint8_t *bytes = UArray_bytes(self); 131 | for (i = 0; i < max; i ++) 132 | { 133 | if (UArray_SizeOfUTF8Char(bytes + i) > 1) return 1; 134 | } 135 | //UARRAY_INTFOREACH(self, i, v, if (ismbchar((int)v)) return 1; ); 136 | } 137 | 138 | return 0; 139 | } 140 | 141 | int UArray_isLegalUTF8(const UArray *self) 142 | { 143 | void *sourceStart = self->data; 144 | void *sourceEnd = self->data + self->size * self->itemSize; 145 | 146 | return isLegalUTF8Sequence(sourceStart, sourceEnd); 147 | } 148 | 149 | UArray *UArray_asNumberArrayString(const UArray *self) 150 | { 151 | UArray *out = UArray_new(); 152 | UArray_setEncoding_(out, CENCODING_ASCII); 153 | 154 | UARRAY_INTFOREACH(self, i, v, 155 | char s[128]; 156 | 157 | if(UArray_isFloatType(self)) 158 | { 159 | sprintf(s, "%f", (double)v); 160 | } 161 | else 162 | { 163 | sprintf(s, "%i", (int)v); 164 | } 165 | 166 | if(i != UArray_size(self) -1 ) strcat(s, ", "); 167 | UArray_appendBytes_size_(out, (unsigned char *)s, strlen(s)); 168 | ); 169 | 170 | return out; 171 | } 172 | 173 | UArray *UArray_asUTF8(const UArray *self) 174 | { 175 | UArray *out = UArray_new(); 176 | UArray_setItemType_(out, CTYPE_uint8_t); 177 | UArray_setEncoding_(out, CENCODING_UTF8); 178 | UArray_setSize_(out, self->size * 4); 179 | 180 | { 181 | //ConversionFlags options = lenientConversion; 182 | void *sourceStart = self->data; 183 | //void *sourceEnd = self->data + self->size * self->itemSize; 184 | UTF8 *targetStart = out->data; 185 | //UTF8 *targetEnd = out->data + out->size * out->itemSize; 186 | size_t outSize; 187 | 188 | switch(self->encoding) 189 | { 190 | case CENCODING_ASCII: 191 | UArray_copy_(out, self); 192 | break; 193 | case CENCODING_UTF8: 194 | UArray_copy_(out, self); 195 | break; 196 | /* 197 | case CENCODING_UTF16: 198 | r = ConvertUTF16toUTF8((const UTF16 **)&sourceStart, (const UTF16 *)sourceEnd, &targetStart, targetEnd, options); 199 | break; 200 | case CENCODING_UTF32: 201 | r = ConvertUTF32toUTF8((const UTF32 **)&sourceStart, (const UTF32 *)sourceEnd, &targetStart, targetEnd, options); 202 | break; 203 | */ 204 | case CENCODING_UCS2: 205 | // should the size be the num of chars or num of bytes?????????? 206 | outSize = ucs2encode(targetStart, sourceStart, self->size, NULL); // ucs2 to utf8 207 | UArray_setSize_(out, outSize - 1); 208 | break; 209 | case CENCODING_UCS4: 210 | // should the size be the num of chars or num of bytes?????????? 211 | outSize = ucs4encode(targetStart, sourceStart, self->size, NULL); // ucs4 to utf8 212 | UArray_setSize_(out, outSize - 1); 213 | break; 214 | case CENCODING_NUMBER: 215 | { 216 | UArray *nas = UArray_asNumberArrayString(self); 217 | UArray_free(out); 218 | out = UArray_asUTF8(nas); 219 | UArray_free(nas); 220 | break; 221 | } 222 | default: 223 | printf("UArray_asUTF8 - unknown source encoding\n"); 224 | } 225 | } 226 | 227 | return out; 228 | } 229 | 230 | int UArray_isUTF8Compatible(const UArray *self) 231 | { 232 | return (self->encoding == CENCODING_ASCII || self->encoding == CENCODING_UTF8); 233 | } 234 | 235 | UArray *UArray_asUCS2(const UArray *self) 236 | { 237 | int convertToUtf8First = !UArray_isUTF8Compatible(self); 238 | const UArray *utf8Array = convertToUtf8First ? UArray_asUTF8(self) : self; 239 | size_t countedChars = UArray_numberOfCharacters(self); 240 | size_t numChars; 241 | 242 | UArray *out = UArray_new(); 243 | UArray_setItemType_(out, CTYPE_uint16_t); 244 | UArray_setEncoding_(out, CENCODING_UCS2); 245 | UArray_setSize_(out, countedChars*2); 246 | 247 | numChars = ucs2decode((ucs2 *)(out->data), out->size, utf8Array->data); 248 | 249 | if ((numChars > 0) && (numChars > countedChars*2)) 250 | { 251 | printf("UArray_asUCS2 error: numChars (%i) > countedChars (2*%i)\n", (int)numChars, (int)countedChars); 252 | printf("Exiting because we may have overwritten the usc2 decode output buffer."); 253 | exit(-1); 254 | } 255 | 256 | UArray_setSize_(out, numChars); 257 | 258 | if (convertToUtf8First) UArray_free((UArray *)utf8Array); 259 | return out; 260 | } 261 | 262 | UArray *UArray_asUCS4(const UArray *self) 263 | { 264 | int convertToUtf8First = !UArray_isUTF8Compatible(self); 265 | const UArray *utf8Array = convertToUtf8First ? UArray_asUTF8(self) : self; 266 | size_t countedChars = UArray_numberOfCharacters(self); 267 | size_t numChars; 268 | 269 | UArray *out = UArray_new(); 270 | UArray_setItemType_(out, CTYPE_uint32_t); 271 | UArray_setEncoding_(out, CENCODING_UCS4); 272 | UArray_setSize_(out, countedChars*2); 273 | 274 | numChars = ucs4decode((ucs4 *)out->data, out->size, utf8Array->data); 275 | 276 | if ((numChars > 0) && (numChars > countedChars*2)) 277 | { 278 | printf("UArray_asUCS4 error: numChars %i != countedChars %i\n", (int)numChars, (int)countedChars); 279 | exit(-1); 280 | } 281 | 282 | UArray_setSize_(out, numChars); 283 | 284 | if (convertToUtf8First) UArray_free((UArray *)utf8Array); 285 | return out; 286 | } 287 | 288 | void UArray_convertToUTF8(UArray *self) 289 | { 290 | UArray *a = UArray_asUTF8(self); 291 | UArray_swapWith_(self, a); 292 | UArray_free(a); 293 | } 294 | 295 | void UArray_convertToUCS2(UArray *self) 296 | { 297 | UArray *a = UArray_asUCS2(self); 298 | UArray_swapWith_(self, a); 299 | UArray_free(a); 300 | } 301 | 302 | void UArray_convertToUCS4(UArray *self) 303 | { 304 | UArray *a = UArray_asUCS4(self); 305 | UArray_swapWith_(self, a); 306 | UArray_free(a); 307 | } 308 | -------------------------------------------------------------------------------- /source/UArray_utf.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | BASEKIT_API int UArray_convertToFixedSizeType(UArray *self); 7 | 8 | BASEKIT_API size_t UArray_numberOfCharacters(const UArray *self); // returns 0 on error 9 | 10 | BASEKIT_API int UArray_maxCharSize(const UArray *self); 11 | BASEKIT_API int UArray_isMultibyte(const UArray *self); 12 | BASEKIT_API int UArray_isLegalUTF8(const UArray *self); 13 | 14 | BASEKIT_API UArray *UArray_asUTF8(const UArray *self); 15 | BASEKIT_API UArray *UArray_asUCS2(const UArray *self); 16 | BASEKIT_API UArray *UArray_asUCS4(const UArray *self); 17 | 18 | BASEKIT_API void UArray_convertToUTF8(UArray *self); 19 | BASEKIT_API void UArray_convertToUCS2(UArray *self); 20 | BASEKIT_API void UArray_convertToUCS4(UArray *self); 21 | -------------------------------------------------------------------------------- /source/_new/Directory.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | 5 | /* ----------------------------------------------------- */ 6 | 7 | #include 8 | 9 | #ifndef _WIN32 10 | #include 11 | #include 12 | 13 | /*#ifdef __CYGWIN__*/ 14 | #include 15 | /*#endif*/ 16 | #else 17 | #include 18 | #define S_IRGRP 0 19 | #define S_IXGRP 0 20 | #define S_IROTH 0 21 | #define S_IXOTH 0 22 | #define S_IRWXU 0 23 | 24 | #define DT_DIR 0x01 25 | 26 | struct dirent { 27 | char d_name[MAX_PATH]; 28 | unsigned char d_type; 29 | }; 30 | 31 | typedef struct { 32 | WIN32_FIND_DATA wfd; 33 | HANDLE hFind; 34 | struct dirent de; 35 | unsigned char valid; 36 | } DIR; 37 | 38 | static DIR *opendir(char *pSpec) 39 | { 40 | DIR *pDir = malloc(sizeof *pDir); 41 | char *longer_string = malloc((strlen(pSpec) + 3) * sizeof *longer_string); 42 | 43 | strcpy(longer_string, pSpec); 44 | strcat(longer_string, "/*"); 45 | pDir->hFind = FindFirstFile(longer_string, &pDir->wfd); 46 | free(longer_string); 47 | pDir->valid = pDir->hFind != INVALID_HANDLE_VALUE; 48 | return pDir; 49 | } 50 | 51 | static void closedir(DIR * pDir) 52 | { 53 | if (pDir->hFind != INVALID_HANDLE_VALUE) 54 | FindClose(pDir->hFind); 55 | free(pDir); 56 | } 57 | 58 | static struct dirent *readdir(DIR *pDir) 59 | { 60 | if (pDir->valid) 61 | { 62 | strcpy(pDir->de.d_name, pDir->wfd.cFileName); 63 | pDir->de.d_type = (pDir->wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ? DT_DIR : 0; 64 | pDir->valid = FindNextFile(pDir->hFind, &pDir->wfd); 65 | return &pDir->de; 66 | } 67 | return NULL; 68 | } 69 | 70 | typedef int mode_t; 71 | 72 | int mkdir(const char *path, mode_t mode) 73 | { 74 | /* returns zero on sucess */ 75 | LPCTSTR lpPathName = path; 76 | LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL; 77 | return (CreateDirectory(lpPathName, lpSecurityAttributes) != 0); 78 | } 79 | 80 | #endif 81 | 82 | #if defined(__CYGWIN__) || defined(sun) || defined(__sun) 83 | int isDirectory(struct dirent *dp, char *path); 84 | { 85 | struct stat st; 86 | /*fstat( dp->d_fd, &st );*/ 87 | stat(pathString, &st); 88 | return ( (st.st_mode & S_IFMT) == S_IFDIR ); 89 | } 90 | #else 91 | int isDirectory(struct dirent *dp, char *path) 92 | { 93 | return (dp->d_type == DT_DIR); 94 | } 95 | #endif 96 | 97 | /* ----------------------------------------------------- */ 98 | 99 | typedef struct 100 | { 101 | char *path; 102 | DIR *dir; 103 | char *next; 104 | } DirEnum; 105 | 106 | DirEnum *DirEnum_new(void) 107 | { 108 | DirEnum *self = calloc(1, sizeof(DirEnum)); 109 | return self; 110 | } 111 | 112 | void DirEnum_free(DirEnum *self) 113 | { 114 | if (self->path) free(self->path); 115 | free(self); 116 | } 117 | 118 | void DirEnum_setPath_(DirEnum *self, char *s) 119 | { 120 | self->path = strcpy(realloc(self->path, strlen(s) + 1), s); 121 | self->dir = opendir(s); 122 | } 123 | 124 | char *DirEnum_setNext_(DirEnum *self, char *s) 125 | { 126 | self->next = strcpy(realloc(self->next, strlen(s) + 1), s); 127 | return self->next; 128 | } 129 | 130 | char *DirEnum_next(DirEnum *self) 131 | { 132 | struct direct *dp = readdir(dirp); 133 | if (dp) 134 | { 135 | char *name = dp.d_name; 136 | } 137 | } 138 | 139 | -------------------------------------------------------------------------------- /source/cdecode.c: -------------------------------------------------------------------------------- 1 | /* 2 | cdecoder.c - c source to a base64 decoding algorithm implementation 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #include "cdecode.h" 9 | 10 | int base64_decode_value(char value_in) 11 | { 12 | static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51}; 13 | static const char decoding_size = sizeof(decoding); 14 | value_in -= 43; 15 | if (value_in < 0 || value_in > decoding_size) return -1; 16 | return decoding[(int)value_in]; 17 | } 18 | 19 | void base64_init_decodestate(base64_decodestate* state_in) 20 | { 21 | state_in->step = step_a; 22 | state_in->plainchar = 0; 23 | } 24 | 25 | int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in) 26 | { 27 | const char* codechar = code_in; 28 | char* plainchar = plaintext_out; 29 | char fragment; 30 | 31 | *plainchar = state_in->plainchar; 32 | 33 | switch (state_in->step) 34 | { 35 | while (1) 36 | { 37 | case step_a: 38 | do { 39 | if (codechar == code_in+length_in) 40 | { 41 | state_in->step = step_a; 42 | state_in->plainchar = *plainchar; 43 | return (int)(plainchar - plaintext_out); 44 | } 45 | fragment = (char)base64_decode_value(*codechar++); 46 | } while (fragment < 0); 47 | *plainchar = (fragment & 0x03f) << 2; 48 | case step_b: 49 | do { 50 | if (codechar == code_in+length_in) 51 | { 52 | state_in->step = step_b; 53 | state_in->plainchar = *plainchar; 54 | return (int)(plainchar - plaintext_out); 55 | } 56 | fragment = (char)base64_decode_value(*codechar++); 57 | } while (fragment < 0); 58 | *plainchar++ |= (fragment & 0x030) >> 4; 59 | *plainchar = (fragment & 0x00f) << 4; 60 | case step_c: 61 | do { 62 | if (codechar == code_in+length_in) 63 | { 64 | state_in->step = step_c; 65 | state_in->plainchar = *plainchar; 66 | return (int)(plainchar - plaintext_out); 67 | } 68 | fragment = (char)base64_decode_value(*codechar++); 69 | } while (fragment < 0); 70 | *plainchar++ |= (fragment & 0x03c) >> 2; 71 | *plainchar = (fragment & 0x003) << 6; 72 | case step_d: 73 | do { 74 | if (codechar == code_in+length_in) 75 | { 76 | state_in->step = step_d; 77 | state_in->plainchar = *plainchar; 78 | return (int)(plainchar - plaintext_out); 79 | } 80 | fragment = (char)base64_decode_value(*codechar++); 81 | } while (fragment < 0); 82 | *plainchar++ |= (fragment & 0x03f); 83 | } 84 | } 85 | /* control should not reach here */ 86 | return (int)(plainchar - plaintext_out); 87 | } 88 | -------------------------------------------------------------------------------- /source/cdecode.h: -------------------------------------------------------------------------------- 1 | /* 2 | cdecode.h - c header for a base64 decoding algorithm 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifndef BASE64_CDECODE_H 9 | #define BASE64_CDECODE_H 10 | 11 | typedef enum 12 | { 13 | step_a, step_b, step_c, step_d 14 | } base64_decodestep; 15 | 16 | typedef struct 17 | { 18 | base64_decodestep step; 19 | char plainchar; 20 | } base64_decodestate; 21 | 22 | void base64_init_decodestate(base64_decodestate* state_in); 23 | 24 | int base64_decode_value(char value_in); 25 | 26 | int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in); 27 | 28 | #endif /* BASE64_CDECODE_H */ 29 | -------------------------------------------------------------------------------- /source/cencode.c: -------------------------------------------------------------------------------- 1 | /* 2 | cencoder.c - c source to a base64 encoding algorithm implementation 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #include "cencode.h" 9 | #include 10 | 11 | const int CHARS_PER_LINE = 72; 12 | 13 | void base64_init_encodestate(base64_encodestate* state_in) 14 | { 15 | state_in->step = step_A; 16 | state_in->result = 0; 17 | state_in->stepcount = 0; 18 | } 19 | 20 | char base64_encode_value(char value_in) 21 | { 22 | static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 23 | if (value_in > 63) return '='; 24 | return encoding[(int)value_in]; 25 | } 26 | 27 | int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in) 28 | { 29 | const char* plainchar = plaintext_in; 30 | const char* const plaintextend = plaintext_in + length_in; 31 | char* codechar = code_out; 32 | char result; 33 | char fragment; 34 | 35 | result = state_in->result; 36 | 37 | switch (state_in->step) 38 | { 39 | while (1) 40 | { 41 | case step_A: 42 | if (plainchar == plaintextend) 43 | { 44 | state_in->result = result; 45 | state_in->step = step_A; 46 | return codechar - code_out; 47 | } 48 | fragment = *plainchar++; 49 | result = (fragment & 0x0fc) >> 2; 50 | *codechar++ = base64_encode_value(result); 51 | result = (fragment & 0x003) << 4; 52 | case step_B: 53 | if (plainchar == plaintextend) 54 | { 55 | state_in->result = result; 56 | state_in->step = step_B; 57 | return codechar - code_out; 58 | } 59 | fragment = *plainchar++; 60 | result |= (fragment & 0x0f0) >> 4; 61 | *codechar++ = base64_encode_value(result); 62 | result = (fragment & 0x00f) << 2; 63 | case step_C: 64 | if (plainchar == plaintextend) 65 | { 66 | state_in->result = result; 67 | state_in->step = step_C; 68 | return codechar - code_out; 69 | } 70 | fragment = *plainchar++; 71 | result |= (fragment & 0x0c0) >> 6; 72 | *codechar++ = base64_encode_value(result); 73 | result = (fragment & 0x03f) >> 0; 74 | *codechar++ = base64_encode_value(result); 75 | 76 | ++(state_in->stepcount); 77 | if (state_in->stepcount == CHARS_PER_LINE/4) 78 | { 79 | *codechar++ = '\n'; 80 | state_in->stepcount = 0; 81 | } 82 | } 83 | } 84 | /* control should not reach here */ 85 | return codechar - code_out; 86 | } 87 | 88 | int base64_encode_blockend(char* code_out, base64_encodestate* state_in) 89 | { 90 | char* codechar = code_out; 91 | 92 | switch (state_in->step) 93 | { 94 | case step_B: 95 | *codechar++ = base64_encode_value(state_in->result); 96 | *codechar++ = '='; 97 | *codechar++ = '='; 98 | break; 99 | case step_C: 100 | *codechar++ = base64_encode_value(state_in->result); 101 | *codechar++ = '='; 102 | break; 103 | case step_A: 104 | break; 105 | } 106 | *codechar++ = '\n'; 107 | 108 | return codechar - code_out; 109 | } 110 | -------------------------------------------------------------------------------- /source/cencode.h: -------------------------------------------------------------------------------- 1 | /* 2 | cencode.h - c header for a base64 encoding algorithm 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifndef BASE64_CENCODE_H 9 | #define BASE64_CENCODE_H 10 | 11 | typedef enum 12 | { 13 | step_A, step_B, step_C 14 | } base64_encodestep; 15 | 16 | typedef struct 17 | { 18 | base64_encodestep step; 19 | char result; 20 | int stepcount; 21 | } base64_encodestate; 22 | 23 | void base64_init_encodestate(base64_encodestate* state_in); 24 | 25 | char base64_encode_value(char value_in); 26 | 27 | int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in); 28 | 29 | int base64_encode_blockend(char* code_out, base64_encodestate* state_in); 30 | 31 | #endif /* BASE64_CENCODE_H */ 32 | 33 | -------------------------------------------------------------------------------- /source/simd_cph/LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004 Patrick Roberts 3 | 4 | This software is provided 'as-is', without any express 5 | or implied warranty. In no event will the authors be held 6 | liable for any damages arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any 9 | purpose, including commercial applications, and to alter it 10 | and redistribute it freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; 13 | you must not claim that you wrote the original software. 14 | If you use this software in a product, an acknowledgment in 15 | the product documentation would be appreciated but is not required. 16 | 17 | 2. Altered source versions must be plainly marked as such, 18 | and must not be misrepresented as being the original software. 19 | 20 | 3. This notice may not be removed or altered from any source distribution. 21 | 22 | 4. THIS LICENSE MAY NOT BE CHANGED, ASSIGNED, OR MIGRATED WITHOUT 23 | THE AUTHOR'S WRITTEN PERMISSION, WITH THE FOLLOWING EXCEPTIONS: 24 | 25 | a. This file may be included with GPL/LGPL licensed 26 | software, but you may not change the license this file 27 | is released under. 28 | */ 29 | -------------------------------------------------------------------------------- /source/simd_cph/docs/LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004 Patrick Roberts 3 | 4 | This software is provided 'as-is', without any express 5 | or implied warranty. In no event will the authors be held 6 | liable for any damages arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any 9 | purpose, including commercial applications, and to alter it 10 | and redistribute it freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; 13 | you must not claim that you wrote the original software. 14 | If you use this software in a product, an acknowledgment in 15 | the product documentation would be appreciated but is not required. 16 | 17 | 2. Altered source versions must be plainly marked as such, 18 | and must not be misrepresented as being the original software. 19 | 20 | 3. This notice may not be removed or altered from any source distribution. 21 | 22 | 4. THIS LICENSE MAY NOT BE CHANGED, ASSIGNED, OR MIGRATED WITHOUT 23 | THE AUTHOR'S WRITTEN PERMISSION, WITH THE FOLLOWING EXCEPTIONS: 24 | 25 | a. This file may be included with GPL/LGPL licensed 26 | software, but you may not change the license this file 27 | is released under. 28 | */ 29 | -------------------------------------------------------------------------------- /source/simd_cph/include/simd_cp.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004 Patrick Roberts 3 | 4 | This software is provided 'as-is', without any express 5 | or implied warranty. In no event will the authors be held 6 | liable for any damages arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any 9 | purpose, including commercial applications, and to alter it 10 | and redistribute it freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; 13 | you must not claim that you wrote the original software. 14 | If you use this software in a product, an acknowledgment in 15 | the product documentation would be appreciated but is not required. 16 | 17 | 2. Altered source versions must be plainly marked as such, 18 | and must not be misrepresented as being the original software. 19 | 20 | 3. This notice may not be removed or altered from any source distribution. 21 | 22 | 4. THIS LICENSE MAY NOT BE CHANGED, ASSIGNED, OR MIGRATED WITHOUT 23 | THE AUTHOR'S WRITTEN PERMISSION, WITH THE FOLLOWING EXCEPTIONS: 24 | 25 | a. This file may be included with GPL/LGPL licensed 26 | software, but you may not change the license this file 27 | is released under. 28 | */ 29 | 30 | 31 | /***************************************************** 32 | 33 | Cross-platform SIMD intrinsics header file 34 | 35 | This is the main file and the only one an application should 36 | include. It will find the correct (hopefully) SIMD_CPH 37 | dialect file to include. 38 | 39 | 40 | */ 41 | 42 | #ifndef __SIMD_CPHD_h 43 | 44 | 45 | /* Defines */ 46 | /* Defines */ 47 | /* Defines */ 48 | #define __SIMD_CPHD_h 49 | 50 | 51 | /* Figure out what compiler and CPU we have */ 52 | 53 | #if defined (__SIMD_NO_SIMD__) || defined (__SIMD_EMU__) 54 | #else /* broken pre-processor */ 55 | 56 | #ifdef __GNUC__ /* gcc compiler */ 57 | 58 | /* x86 compiler */ 59 | #ifdef __i386__ 60 | #define __GNUC__X86__ 61 | #define __FOUND 62 | #endif 63 | 64 | /* PowerPC Compiler */ 65 | #ifdef __ALTIVEC__ 66 | #define __GNUC__RS6__ 67 | #define __FOUND 68 | #define __SIMD_NO_SIMD /* No PPC intrinsics file right now */ 69 | #endif 70 | 71 | #ifdef __XSCALE__ 72 | #define __GNUC__ARM_IWMMX__ 73 | #define __FOUND 74 | #endif 75 | 76 | #endif /* __GNUC__ */ 77 | 78 | 79 | 80 | #ifdef _MSC_VER /* Microsoft VC Compiler */ 81 | 82 | #ifdef _M_IX86 /* MSVC for X86 CPU (same as GNUC?)*/ 83 | #define __MSVC__X86__ 84 | #define __FOUND 85 | #endif 86 | 87 | #ifdef _M_ALPHA /* for Compaq Alpha CPU */ 88 | #define __MSVC__AXP__ 89 | #define __FOUND 90 | #define __SIMD_NO_SIMD__ 91 | #endif 92 | 93 | #endif /* _WIN32 */ 94 | 95 | 96 | 97 | #ifndef __FOUND 98 | #define __SIMD_EMU__ 99 | //#warning simd_cp.h does not support or could not figure out your compiler and/or CPU. 100 | #endif 101 | 102 | #endif /* SIMD_NO_SIMD and SIMD_EMU */ 103 | 104 | 105 | /* Include the correct SIMD file */ 106 | 107 | #if defined(__SIMD_NO_SIMD__) || defined(__SIMD_EMU__) 108 | #warning Including Emulated SIMD support... 109 | #define __UNK__EMU__ 110 | #include 111 | #endif 112 | 113 | #if defined( __GNUC__X86__ ) || defined(__MSVC__X86__) 114 | /* gcc x86 compiler or msvc x86 */ 115 | #include 116 | #endif /* __GNUC__X86__ */ 117 | 118 | #ifdef __GNUC__ARM_IWMMX /* gcc ARM compiler with XSCALE SIMD */ 119 | #include 120 | #endif 121 | 122 | 123 | /* Generic Helper commands */ 124 | /* Generic Helper commands */ 125 | /* Generic Helper commands */ 126 | 127 | /* print a simd_m128 variable: l=label to print, a=simd_m128 variable */ 128 | #define simd_print4Floats(l,a) printf("%s: %f %f %f %f\n",l,a.f[0],a.f[1],a.f[2],a.f[3]) 129 | #define simd_print4Ints(l,a) printf("%s: %d %d %d %d\n",l,a.i[0],a.i[1],a.i[2],a.i[3]) 130 | #define simd_print4UInts(l,a) printf("%s: %d %d %d %d\n",l,(unsigned int)a.i[0],(unsigned int)a.i[1],(unsigned int)a.i[2],(unsigned int)a.i[3]) 131 | #define simd_print4Hex(l,a) printf("%s: 0x%08x 0x%08x 0x%08x 0x%08x\n",l,a.i[0],a.i[1],a.i[2],a.i[3]) 132 | 133 | 134 | #endif /* CP_SIMD_h */ 135 | -------------------------------------------------------------------------------- /source/simd_cph/simd_cph.readme: -------------------------------------------------------------------------------- 1 | /***************************************************** 2 | 3 | Cross-platform SIMD intrinsics header file 4 | 5 | VERSION: 2004.10.26 (alpha) 6 | 7 | Created by Patrick Roberts 8 | 9 | This is an on-going project. Please add functions and 10 | typedefs as needed, but try to follow the guideline 11 | below: 12 | 13 | The goal of this file is to stay cross-platform. 14 | Only intrinsics or #defines that mimic another system's 15 | SIMD instruction should be included, with the only exception 16 | being instructions that, if non existant, are not 17 | needed (see bottom) 18 | 19 | Currently, the goal is to base support around 128-bit SIMD. 20 | (Only the Gekko and x86-MMX are 64-bit) 21 | 22 | Changelog: 23 | 24 | 2004.05.09 [Patrick Roberts] 25 | *) Created file with some i386, GCC dialect 26 | 2004.10.22 [Patrick Roberts] 27 | *) Created emulated SIMD 28 | 2004.10.25 [Patrick Roberts] 29 | *) Created arm-iwmmx GCC dialect 30 | *) Fixed sqrt bug in emu dialect 31 | *) Organized directories 32 | *) Makefile for test app 33 | 34 | 35 | To Do: 36 | 37 | *( Docs 38 | *( Add new intrinsics to test app 39 | *( MinGW x86 dialect (same as GCC on Linux?) 40 | *( Does 3DNOW buy us anything? 41 | *( Intel ICC x86 dialect 42 | *( MSVC .NET x86 dialect 43 | *( Support for ARM ARM6, VFP and NEON SIMD? What compilers use these? 44 | *( PowerPC AltiVec/Velocity/VMX components 45 | *( MIPS-MMI / PS2-VU components 46 | *( See if SSE2 buys us anything beyond what the compiler does already 47 | *( Compaq Alpha components 48 | 49 | */ 50 | 51 | /*************************************************** 52 | 53 | Platform Notes: 54 | 55 | 56 | General 57 | ------- 58 | 59 | NOTE: Code must be 16-byte aligned. Align to 16 when allocating memory. 60 | 61 | X86/XSCALE (Intel) vs. PowerPC/MIPS 62 | 63 | While the PowerPC and MIPS SIMD instructions take 2 source vectors 64 | and a destination vector, the Intel platforms only take a source and 65 | destination. Example: 66 | 67 | PPC/MIPS can do: 68 | 69 | C = A + B 70 | 71 | X86 can only do: 72 | 73 | A = A + B (or A+=B) 74 | 75 | Code written either way will work on the X86, and still be faster than 76 | 387 math, but preserving the registers takes significant overhead. 77 | (Disassemble the test program for an example. The prints preserve, the 78 | 'disassembly test' does not.) For the fastest code between systems, write 79 | your SIMD math as the X86 expects, manually preserving SIMD variables. 80 | At least GCC for PPC doesn't seem to have any issues figuring out how to 81 | deal with a source and destination memory address being the same. 82 | 83 | 84 | GCC x86 85 | ------- 86 | 87 | You must compile with -msse and -mmmx. I try to avoid mmx as mmx is slower on 88 | the P4 than on the P3 and XP, but sse doesn't have integer math. 89 | 90 | You may want to set -msse2 if you have a P4 CPU (-msse2 is set by default 91 | for x86-64 CPUS), as some of the simd functions not supported on x86 92 | can be sped up by gcc using sse2 commands rather than standard pipeline 93 | commands. 94 | 95 | 96 | GCC PowerPC 97 | ----------- 98 | 99 | You must compile with the switch -maltivec 100 | 101 | 102 | GCC ARM (Xscale only) 103 | ---------------- 104 | 105 | GCC ARM only seems to support Intel Wirekess MMX (XSCALE), not ARMv6, 106 | Neon, or VFP? (Are these all the same beast?) 107 | 108 | You must compile with +iwmmxt 109 | 110 | 111 | */ 112 | -------------------------------------------------------------------------------- /source/simd_cph/test/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CC = gcc 3 | 4 | # X86 5 | #COPTS = -I../include -g -O2 -mmmx -msse 6 | #PLATFORM = X86 7 | DIS = objdump -d -S 8 | 9 | # EMULATED 10 | COPTS = -I../include -D__SIMD_EMU__ -g -O2 11 | PLATFORM = emu 12 | 13 | default: test_simd.c emulated 14 | ${CC} ${COPTS} -o test_simd_${PLATFORM} test_simd.c 15 | 16 | emulated: test_simd.c 17 | ${CC} ${COPTS} -D__SIMD_EMU__ -o test_simd_emu test_simd.c 18 | 19 | xdiff: default emulated 20 | ${DIS} test_simd_${PLATFORM} > test_simd_${PLATFORM}.dis 21 | ${DIS} test_simd_emu > test_simd_emu.dis 22 | xdiff test_simd_emu.dis test_simd_${PLATFORM}.dis 23 | 24 | clean: 25 | rm test_simd_${PLATFORM} test_simd_emu *.dis 26 | -------------------------------------------------------------------------------- /source/simd_cph/test/test_simd.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004 Patrick Roberts 3 | 4 | This software is provided 'as-is', without any express 5 | or implied warranty. In no event will the authors be held 6 | liable for any damages arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any 9 | purpose, including commercial applications, and to alter it 10 | and redistribute it freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; 13 | you must not claim that you wrote the original software. 14 | If you use this software in a product, an acknowledgment in 15 | the product documentation would be appreciated but is not required. 16 | 17 | 2. Altered source versions must be plainly marked as such, 18 | and must not be misrepresented as being the original software. 19 | 20 | 3. This notice may not be removed or altered from any source distribution. 21 | 22 | 4. THIS LICENSE MAY NOT BE CHANGED, ASSIGNED, OR MIGRATED WITHOUT 23 | THE AUTHOR'S WRITTEN PERMISSION, WITH THE FOLLOWING EXCEPTIONS: 24 | 25 | a. This file may be included with GPL/LGPL licensed 26 | software, but you may not change the license this file 27 | is released under. 28 | */ 29 | 30 | 31 | /* uncomment the line below to force SIMD emulation C code */ 32 | /*#define __SIMD_EMU__ */ 33 | 34 | #include 35 | #include 36 | 37 | int main(void) { 38 | 39 | simd_m128 v0,v1,v2; 40 | 41 | simd_load4Floats(v1,2.0,2.0,2.0,2.0); 42 | simd_load4Floats(v2,10.0,20.0,30.0,40.0); 43 | 44 | printf("\nChecking 4f commands\n"); 45 | 46 | simd_print4Floats("v1 ",v1); 47 | simd_print4Floats("v2 ",v2); 48 | puts(""); 49 | 50 | /* v0 = v1 + v2 */ 51 | simd_4f_add(v1,v2,v0); 52 | simd_print4Floats("4f_add ",v0); 53 | 54 | /* v0 = v1 - v2 */ 55 | simd_4f_sub(v1,v2,v0); 56 | simd_print4Floats("4f_sub ",v0); 57 | 58 | /* v0 = v1 * v2 */ 59 | simd_4f_mult(v1,v2,v0); 60 | simd_print4Floats("4f_mult",v0); 61 | 62 | /* v0 = v1 / v2 */ 63 | simd_4f_div(v1,v2,v0); 64 | simd_print4Floats("4f_div",v0); 65 | 66 | /* 67 | * If you look at the disassembly of this section on an X86 processor, it will be 68 | * very tight, as X86 SSE/MMX only handles 2 regs- i.e. A+=B, instead of C=A+B. 69 | * For the best cross-platform performance, cater to the lowest demoninator and 70 | * write your code like this. 71 | */ 72 | 73 | printf("\ndisassembly test\n"); 74 | simd_4f_add(v1,v2,v1); 75 | simd_4f_mult(v1,v2,v1); 76 | simd_4f_sub(v1,v2,v1); 77 | simd_4f_div(v1,v2,v1); 78 | 79 | 80 | 81 | printf("\nChecking 4i commands\n"); 82 | 83 | simd_load4Ints(v1,20,30,40,50); 84 | simd_load4Ints(v2,2,3,4,5); 85 | 86 | simd_print4Ints("v1 ",v1); 87 | simd_print4Ints("v2 ",v2); 88 | puts(""); 89 | 90 | 91 | /* v0 = v1 + v2 */ 92 | simd_4i_add(v1,v2,v0); 93 | simd_print4Ints("4i_add ",v0); 94 | 95 | /* v0 = v1 - v2 */ 96 | simd_4i_sub(v1,v2,v0); 97 | simd_print4Ints("4i_sub ",v0); 98 | 99 | /* v0 = v1 * v2 */ 100 | simd_4i_mult(v1,v2,v0); 101 | simd_print4Ints("4i_mult",v0); 102 | 103 | /* v0 = v1 / v2 */ 104 | simd_4i_div(v1,v2,v0); 105 | simd_print4Ints("4i_div ",v0); 106 | 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /source/simd_cph/test/test_simd_emu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevedekorte/basekit/a3e54ba83b85f530dc9442a33d2779240ed96189/source/simd_cph/test/test_simd_emu -------------------------------------------------------------------------------- /source/ucs2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Sofia-SIP package 3 | * 4 | * Copyright (C) 2005 Nokia Corporation. 5 | * 6 | * Contact: Pekka Pessi 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation; either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | * 02110-1301 USA 22 | * 23 | */ 24 | 25 | /**@CFILE ucs2.c UCS2 (Unicode, ISO Basic Multilingual Plane) string handling. 26 | * 27 | * @author Pekka Pessi 28 | * 29 | * @date Created: Tue Apr 21 15:32:02 1998 pessi 30 | * 31 | */ 32 | 33 | //#include "config.h" 34 | 35 | #include "utf8.h" 36 | #include "utf8internal.h" 37 | 38 | /* 39 | * Decode utf8 string into ucs2 string, 40 | * return number of ucs2 characters decoded 41 | */ 42 | size_t ucs2decode(ucs2 *dst, size_t dst_size, const utf8 *s) 43 | { 44 | ucs2 v, *d = dst; 45 | 46 | if (s) do { 47 | if (dst_size == 0) 48 | break; 49 | if (IS_UTF8_S1(s)) 50 | v = UCS4_S1(s), s += 1; 51 | else if (IS_UTF8_S2(s)) 52 | v = UCS4_S2(s), s += 2; 53 | else if (IS_UTF8_S3(s)) 54 | v = UCS4_S3(s), s += 3; 55 | else { 56 | s++; 57 | continue; /* skip illegal characters */ 58 | } 59 | *d++ = v; 60 | dst_size--; 61 | } while (*s); 62 | 63 | if (dst_size) 64 | *d = 0; 65 | 66 | return d - dst; 67 | } 68 | 69 | /* 70 | * Encode ucs2 string into utf8 string, 71 | * return number of utf8 bytes encoded including final zero 72 | * 73 | * 'quote' may contain an optional quoting table containing 74 | * non-zero for all ASCII characters to quote 75 | * 76 | */ 77 | size_t ucs2encode(utf8 *dst, const ucs2 *s, size_t n, const char quote[128]) 78 | { 79 | utf8 *d = dst; 80 | ucs2 c; 81 | 82 | if (s) while (n-- > 0) { 83 | c = *s++; 84 | 85 | if (IS_UCS4_1(c)) { 86 | if (quote && quote[c]) { 87 | UTF8_S2(d, c); 88 | d += 2; 89 | } 90 | else { 91 | if (!c) /* zero must be represented as UTF8_2 */ 92 | break; 93 | UTF8_S1(d, (utf8) c); 94 | d += 1; 95 | } 96 | } 97 | else if (IS_UCS4_2(c)) { 98 | UTF8_S2(d, c); 99 | d += 2; 100 | } 101 | else /* if (IS_UCS4_3(c)) */ { 102 | UTF8_S3(d, c); 103 | d += 3; 104 | } 105 | } 106 | 107 | *d++ = 0; 108 | return d - dst; 109 | } 110 | 111 | /* 112 | * Length of UCS2 (BMP, Unicode) string decoded from UTF8 113 | */ 114 | size_t ucs2declen(const utf8 *s) 115 | { 116 | size_t len = 0; 117 | size_t errors = 0; /* errors */ 118 | 119 | UTF8_ANALYZE(s, len, len, len, errors, errors); 120 | 121 | if (errors) 122 | return 0; 123 | 124 | return len; 125 | } 126 | 127 | /* 128 | * Length of UTF8 encoding of a UCS2 string, including final zero 129 | */ 130 | size_t ucs2enclen(const ucs2 *s, size_t n, const char quote[128]) 131 | { 132 | size_t len = 1; 133 | ucs2 c; 134 | 135 | while (n-- > 0) { 136 | c = *s++; 137 | if (c < 0x80u) 138 | if (quote && quote[c]) 139 | len += 2; 140 | else { 141 | if (!c) break; 142 | len += 1; 143 | } 144 | else if (c < 0x800u) 145 | len += 2; 146 | else /* if (c < 0x10000u) */ 147 | len += 3; 148 | } 149 | 150 | return len; 151 | } 152 | 153 | /* 154 | * Length of UCS2 string (number of non-zero UCS2 characters before zero) 155 | */ 156 | size_t ucs2len(ucs2 const *s) 157 | { 158 | size_t len = 0; 159 | 160 | if (s) while (*s++) 161 | len++; 162 | 163 | return len; 164 | } 165 | 166 | /* 167 | * Compare UCS2 (BMP, Unicode) string 168 | */ 169 | int ucs2cmp(ucs2 const *s1, ucs2 const *s2) 170 | { 171 | int retval = s1 - s2; 172 | 173 | if (s1 && s2) 174 | while ((retval = (*s1 - *s2)) && (*s1++) && (*s2++)) 175 | ; 176 | 177 | return retval; 178 | } 179 | 180 | /* 181 | * Compare UCS2 (BMP, Unicode) string 182 | */ 183 | int ucs2ncmp(ucs2 const *s1, ucs2 const *s2, size_t n) 184 | { 185 | int retval = 0; 186 | 187 | if (s1 && s2) 188 | while (n-- > 0 && (retval = (*s1 - *s2)) && (*s1++) && (*s2++)) 189 | ; 190 | 191 | return retval; 192 | } 193 | -------------------------------------------------------------------------------- /source/ucs4.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Sofia-SIP package 3 | * 4 | * Copyright (C) 2005 Nokia Corporation. 5 | * 6 | * Contact: Pekka Pessi 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation; either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | * 02110-1301 USA 22 | * 23 | */ 24 | 25 | /**@CFILE ucs4.c UCS-4 routines 26 | * 27 | * @author Pekka Pessi 28 | * 29 | * @date Created: Tue Apr 21 15:32:02 1998 pessi 30 | */ 31 | 32 | //#include "config.h" 33 | 34 | #include "utf8.h" 35 | #include "utf8internal.h" 36 | 37 | /* 38 | * Decode utf8 string into ucs4 string, 39 | * return number of ucs4 characters decoded 40 | */ 41 | size_t ucs4decode(ucs4 *dst, size_t dst_size, const utf8 *s) 42 | { 43 | ucs4 v, *d = dst; 44 | 45 | if (s) while (*s) { 46 | if (dst_size == 0) 47 | break; 48 | if (IS_UTF8_S1(s)) 49 | v = UCS4_S1(s), s += 1; 50 | else if (IS_UTF8_S2(s)) 51 | v = UCS4_S2(s), s += 2; 52 | else if (IS_UTF8_S3(s)) 53 | v = UCS4_S3(s), s += 3; 54 | else if (IS_UTF8_S4(s)) 55 | v = UCS4_S4(s), s += 4; 56 | else if (IS_UTF8_S5(s)) 57 | v = UCS4_S5(s), s += 5; 58 | else if (IS_UTF8_S6(s)) 59 | v = UCS4_S6(s), s += 6; 60 | else { 61 | s++; 62 | continue; /* skip illegal characters */ 63 | } 64 | *d++ = v; 65 | dst_size--; 66 | }; 67 | 68 | if (dst_size) 69 | *d = 0; 70 | 71 | return d - dst; 72 | } 73 | 74 | /* 75 | * Encode ucs4 string into utf8 string, 76 | * return number of utf8 bytes encoded including final zero 77 | * 78 | * 'quote' may contain an optional quoting table containing 79 | * non-zero for all ASCII characters to quote 80 | * 81 | */ 82 | size_t ucs4encode(utf8 *dst, const ucs4 *s, size_t n, const char quote[128]) 83 | { 84 | utf8 *d = dst; 85 | ucs4 c; 86 | 87 | if (s) while (n-- > 0) { 88 | c = *s++; 89 | 90 | if (IS_UCS4_1(c)) { 91 | if (quote && quote[c]) { 92 | UTF8_S2(d, c); 93 | d += 2; 94 | } 95 | else { 96 | if (!c) /* zero must be represented as UTF8_2 */ 97 | break; 98 | UTF8_S1(d, c); 99 | d += 1; 100 | } 101 | } 102 | else if (IS_UCS4_2(c)) { 103 | UTF8_S2(d, c); 104 | d += 2; 105 | } 106 | else if (IS_UCS4_3(c)) { 107 | UTF8_S3(d, c); 108 | d += 3; 109 | } 110 | else if (IS_UCS4_4(c)) { 111 | UTF8_S4(d, c); 112 | d += 4; 113 | } 114 | else if (IS_UCS4_5(c)) { 115 | UTF8_S5(d, c); 116 | d += 5; 117 | } 118 | else if (IS_UCS4_6(c)) { 119 | UTF8_S6(d, c); 120 | d += 6; 121 | } 122 | else { 123 | /* skip illegal (negative) characters */ 124 | } 125 | } 126 | 127 | *d++ = 0; 128 | return d - dst; 129 | } 130 | 131 | /* 132 | * Length of UCS4 string decoded from UTF8 133 | */ 134 | size_t ucs4declen(const utf8 *s) 135 | { 136 | size_t len = 0; 137 | size_t errors = 0; /* errors */ 138 | 139 | UTF8_ANALYZE(s, len, len, len, len, errors); 140 | 141 | if (errors) 142 | return 0; 143 | 144 | return len; 145 | } 146 | 147 | /* 148 | * Length of UTF8 encoding of a UCS4 string, including final zero 149 | */ 150 | size_t ucs4enclen(const ucs4 *s, size_t n, const char quote[128]) 151 | { 152 | size_t len = 1; 153 | ucs4 c; 154 | 155 | while (n-- > 0) { 156 | c = *s++; 157 | if (c < 0x80u) 158 | if (quote && quote[c]) 159 | len += 2; 160 | else { 161 | if (!c) break; 162 | len += 1; 163 | } 164 | else if (c < 0x800u) 165 | len += 2; 166 | else if (c < 0x10000u) 167 | len += 3; 168 | else if (c < 0x200000u) 169 | len += 4; 170 | else if (c < 0x4000000u) 171 | len += 5; 172 | else if (c < 0x80000000u) 173 | len += 6; 174 | } 175 | 176 | return len; 177 | } 178 | 179 | /* 180 | * Length of UCS4 string (number of non-zero UCS4 characters before zero) 181 | */ 182 | size_t ucs4len(ucs4 const *s) 183 | { 184 | size_t len = 0; 185 | 186 | if (s) while (*s++) 187 | len++; 188 | 189 | return len; 190 | } 191 | 192 | /* 193 | * Compare UCS4 string 194 | */ 195 | int ucs4cmp(ucs4 const *s1, ucs4 const *s2) 196 | { 197 | int retval; 198 | 199 | while ((retval = (*s1 - *s2)) && (*s1++) && (*s2++)) 200 | ; 201 | 202 | return retval; 203 | } 204 | 205 | /* 206 | * Compare UCS4 string prefix 207 | */ 208 | int ucs4ncmp(ucs4 const *s1, ucs4 const *s2, size_t n) 209 | { 210 | int retval = 0; 211 | 212 | while (n-- > 0 && (retval = (*s1 - *s2)) && (*s1++) && (*s2++)) 213 | ; 214 | 215 | return retval; 216 | } 217 | -------------------------------------------------------------------------------- /source/utf8.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Sofia-SIP package 3 | * 4 | * Copyright (C) 2005 Nokia Corporation. 5 | * 6 | * Contact: Pekka Pessi 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation; either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | * 02110-1301 USA 22 | * 23 | */ 24 | 25 | /**@CFILE utf8.c 26 | * 27 | * utf8 string handling. 28 | * 29 | * @author Pekka Pessi 30 | * 31 | * @date Created: Tue Apr 21 15:32:02 1998 pessi 32 | */ 33 | 34 | //#include "config.h" 35 | 36 | #include "utf8.h" 37 | #include "utf8internal.h" 38 | 39 | #ifndef _WIN32 40 | #include 41 | #endif 42 | 43 | /** Width of an UTF8 character cell (1, 2 or 4 bytes) */ 44 | size_t utf8_width(const utf8 *s) 45 | { 46 | size_t w8 = 0, w16 = 0, w32 = 0; 47 | size_t errors = 0; /* errors */ 48 | 49 | UTF8_ANALYZE(s, w8, w8, w16, w32, errors); 50 | 51 | if (errors) 52 | return 0; 53 | 54 | return w32 ? 4 : (w16 ? 2 : 1); 55 | } 56 | 57 | /** Convert UTF8 string @a s to ISO-Latin-1 string @a dst. */ 58 | size_t ucs18decode(char *dst, size_t dst_size, const utf8 *s) 59 | { 60 | #ifndef _WIN32 61 | assert(!"implemented"); 62 | #endif 63 | return 0; 64 | } 65 | 66 | /** Convert ISO-Latin-1 string @a s to UTF8 string in @a dst. */ 67 | size_t ucs1encode(utf8 *dst, const ucs1 *s, size_t n, const char quote[128]) 68 | { 69 | #ifndef _WIN32 70 | assert(!"implemented"); 71 | #endif 72 | return 0; 73 | } 74 | 75 | /** Calculate number of characters in UTF8 string @a s. */ 76 | size_t ucs1declen(const utf8 *s) 77 | { 78 | #ifndef _WIN32 79 | assert(!"implemented"); 80 | #endif 81 | return 0; 82 | } 83 | 84 | /** Calculate length of UTF8 encoding of string @a s. */ 85 | size_t ucs1enclen(const ucs1 *s, size_t n, const char quote[128]) 86 | { 87 | #ifndef _WIN32 88 | assert(!"implemented"); 89 | #endif 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /source/utf8.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Sofia-SIP package 3 | * 4 | * Copyright (C) 2005 Nokia Corporation. 5 | * 6 | * Contact: Pekka Pessi 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation; either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | * 02110-1301 USA 22 | * 23 | */ 24 | 25 | /**@file utf8.h 26 | * Encoding/Decoding Functions for UCS Transformation Format UTF-8. 27 | * 28 | * UTF-8 encoding codes the ISO 10646 (Unicode, UCS2 and UCS4) characters as 29 | * variable length (1 - 6 bytes) strings of 8-bit characters. 30 | * 31 | * @author Pekka Pessi 32 | * 33 | * @date Created: Tue Apr 21 15:32:38 1998 pessi 34 | 35 | * @sa RFC 2279, 36 | * "UTF-8, a transformation format of ISO 10646", 37 | * F. Yergeau. January 1998. 38 | * 39 | */ 40 | 41 | #ifndef UTF8_H /** Defined when has been included */ 42 | #define UTF8_H 43 | 44 | #include "Common.h" 45 | 46 | /* 47 | #ifndef SU_TYPES_H 48 | #include "su_types.h" 49 | #endif 50 | */ 51 | 52 | //SOFIA_BEGIN_DECLS 53 | 54 | typedef unsigned char utf8; 55 | typedef unsigned short utf16; 56 | typedef unsigned char ucs1; 57 | typedef unsigned short ucs2; 58 | typedef unsigned int ucs4; 59 | 60 | size_t utf8_width(const utf8 *); 61 | 62 | /* Latin-1 encoding/decoding */ 63 | size_t ucs18decode(char *dst, size_t dst_size, const utf8 *s); 64 | size_t ucs1encode(utf8 *dst, const ucs1 *s, size_t n, const char quote[128]); 65 | size_t ucs1declen(const utf8 *s); 66 | size_t ucs1enclen(const ucs1 *s, size_t n, const char quote[128]); 67 | 68 | /* UCS2 (BMP) encoding/decoding */ 69 | size_t ucs2decode(ucs2 *dst, size_t dst_size, const utf8 *s); 70 | size_t ucs2encode(utf8 *dst, const ucs2 *s, size_t n, const char quote[128]); 71 | size_t ucs2declen(const utf8 *s); 72 | size_t ucs2enclen(const ucs2 *s, size_t n, const char quote[128]); 73 | 74 | size_t ucs4decode(ucs4 *dst, size_t dst_size, const utf8 *s); 75 | size_t ucs4encode(utf8 *dst, const ucs4 *s, size_t n, const char quote[128]); 76 | size_t ucs4declen(const utf8 *s); 77 | size_t ucs4enclen(const ucs4 *s, size_t n, const char quote[128]); 78 | 79 | size_t ucs2len(ucs2 const *s); 80 | int ucs2cmp(ucs2 const *s1, ucs2 const *s2); 81 | int ucs2ncmp(ucs2 const *s1, ucs2 const *s2, size_t n); 82 | 83 | size_t ucs4len(ucs4 const *s); 84 | int ucs4cmp(ucs4 const *s1, ucs4 const *s2); 85 | int ucs4ncmp(ucs4 const *s1, ucs4 const *s2, size_t n); 86 | 87 | /* 88 | * IS_UCS4_n tests whether UCS4 character should be represented 89 | * with 'n' byte utf8 string 90 | */ 91 | #define IS_UCS4_1(x) ((ucs4)(x) <= 0x7fu) 92 | #define IS_UCS4_2(x) (0x80u <= (ucs4)(x) && (ucs4)(x) <= 0x7ffu) 93 | #define IS_UCS4_3(x) (0x800u <= (ucs4)(x) && (ucs4)(x) <= 0xffffu) 94 | #define IS_UCS4_4(x) (0x10000u <= (ucs4)(x) && (ucs4)(x) <= 0x1fFFFFu) 95 | #define IS_UCS4_5(x) (0x200000u <= (ucs4)(x) && (ucs4)(x) <= 0x3ffFFFFu) 96 | #define IS_UCS4_6(x) (0x4000000u <= (ucs4)(x) && (ucs4)(x) <= 0x7fffFFFFu) 97 | 98 | /* Special test for ISO-8859-1 characters */ 99 | #define IS_UCS4_I(x) (0x80u <= (ucs4)(x) && (ucs4)(x) <= 0xffu) 100 | 101 | /* Length of an UCS4 character in UTF8 encoding */ 102 | #define UTF8_LEN4(x) (IS_UCS4_1(x) || IS_UCS4_2(x) && 2 || \ 103 | IS_UCS4_3(x) && 3 || IS_UCS4_4(x) && 4 || \ 104 | IS_UCS4_5(x) && 5 || IS_UCS4_6(x) && 6) 105 | 106 | /* Length of an UCS2 character in UTF8 encoding */ 107 | #define UTF8_LEN2(x) (IS_UCS4_1(x) || IS_UCS4_2(x) && 2 || IS_UCS4_3(x) && 3) 108 | 109 | /* 110 | * IS_UTF8_n tests the length of the next wide character 111 | */ 112 | #define IS_UTF8_1(c) (0x00 == ((c) & 0x80)) 113 | #define IS_UTF8_2(c) (0xc0 == ((c) & 0xe0)) 114 | #define IS_UTF8_3(c) (0xe0 == ((c) & 0xf0)) 115 | #define IS_UTF8_4(c) (0xf0 == ((c) & 0xf8)) 116 | #define IS_UTF8_5(c) (0xf8 == ((c) & 0xfc)) 117 | #define IS_UTF8_6(c) (0xfc == ((c) & 0xfe)) 118 | 119 | /* Extension byte? */ 120 | #define IS_UTF8_X(c) (0x80 == ((c) & 0xc0)) 121 | /* ISO-8859-1 character? */ 122 | #define IS_UTF8_I(c) (0xc0 == ((c) & 0xfc)) 123 | 124 | #define IS_UTF8_S1(s) \ 125 | (IS_UTF8_1(s[0])) 126 | #define IS_UTF8_S2(s) \ 127 | (IS_UTF8_2(s[0])&&((s)[1]&192)==128) 128 | #define IS_UTF8_SI(s) \ 129 | (IS_UTF8_I(s[0])&&((s)[1]&192)==128) 130 | #define IS_UTF8_S3(s) \ 131 | (IS_UTF8_3(s[0])&& ((s)[1]&192)==128&&((s)[2]&192)==128) 132 | #define IS_UTF8_S4(s) \ 133 | (IS_UTF8_4(s[0])&& ((s)[1]&192)==128&&((s)[2]&192)==128&&((s)[3]&192)==128) 134 | #define IS_UTF8_S5(s) \ 135 | (IS_UTF8_5(s[0])&& ((s)[1]&192)==128&&((s)[2]&192)==128&&\ 136 | ((s)[3]&192)==128&&((s)[4]&192)==128) 137 | #define IS_UTF8_S6(s) \ 138 | (IS_UTF8_6(s[0])&& ((s)[1]&192)==128&&((s)[2]&192)==128&&((s)[3]&192)==128&&\ 139 | ((s)[4]&192)==128&&((s)[5]&192)==128) 140 | 141 | #define UCS4_S1(s) ((ucs4)(s[0])) 142 | #define UCS4_S2(s) ((ucs4)\ 143 | (((s[0])&31)<<6)|((s[1])&63)) 144 | #define UCS4_S3(s) ((ucs4)\ 145 | (((s[0])&15)<<12)|(((s[1])&63)<<6)|((s[2])&63)) 146 | #define UCS4_S4(s) ((ucs4)\ 147 | (((s[0])&7)<<18)|(((s[1])&63)<<12)|(((s[2])&63)<<6)|\ 148 | ((s[3])&63)) 149 | #define UCS4_S5(s) ((ucs4)\ 150 | (((s[0])&3)<<24)|(((s[1])&63)<<18)|(((s[2])&63)<<12)|\ 151 | (((s[3])&63)<<6)|((s[4])&63)) 152 | #define UCS4_S6(s) ((ucs4)\ 153 | (((s[0])&1)<<30)|(((s[1])&63)<<24)|(((s[2])&63)<<18)|\ 154 | (((s[3])&63)<<12)|(((s[4])&63)<<6)|((s[5])&63)) 155 | 156 | #define UTF8_S1(s,c) ((s)[0]=(c)) 157 | #define UTF8_S2(s,c) ((s)[0]=(((c)>>6)&31)|0xc0,\ 158 | (s)[1]=((c)&63)|128) 159 | #define UTF8_S3(s,c) ((s)[0]=(((c)>>12)&15)|0xe0,\ 160 | (s)[1]=((c>>6)&63)|128,\ 161 | (s)[2]=((c)&63)|128) 162 | #define UTF8_S4(s,c) ((s)[0]=(((c)>>18)&7)|0xf0,\ 163 | (s)[1]=((c>>12)&63)|128,\ 164 | (s)[2]=((c>>6)&63)|128,\ 165 | (s)[3]=((c)&63)|128) 166 | #define UTF8_S5(s,c) ((s)[0]=(((c)>>24)&3)|0xf8,\ 167 | (s)[1]=((c>>18)&63)|128,\ 168 | (s)[2]=((c>>12)&63)|128,\ 169 | (s)[3]=((c>>6)&63)|128,\ 170 | (s)[4]=((c)&63)|128) 171 | #define UTF8_S6(s,c) ((s)[0]=(((c)>>30)&1)|0xfc,\ 172 | (s)[1]=((c>>24)&63)|128,\ 173 | (s)[2]=((c>>18)&63)|128,\ 174 | (s)[3]=((c>>12)&63)|128,\ 175 | (s)[4]=((c>>6)&63)|128,\ 176 | (s)[5]=((c)&63)|128) 177 | 178 | //SOFIA_END_DECLS 179 | 180 | #endif /* UTF8_H */ 181 | -------------------------------------------------------------------------------- /source/utf8internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Sofia-SIP package 3 | * 4 | * Copyright (C) 2005 Nokia Corporation. 5 | * 6 | * Contact: Pekka Pessi 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation; either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | * 02110-1301 USA 22 | * 23 | */ 24 | 25 | #ifndef UTF8INTERNAL_H 26 | #define UTF8INTERNAL_H 27 | 28 | /**@IFILE utf8internal.h 29 | * UTF-8 macros. 30 | * 31 | * @author Pekka Pessi 32 | * 33 | * @date Created: Tue Apr 21 15:32:02 1998 pessi 34 | */ 35 | 36 | #define UTF8_ANALYZE(s, ascii, latin1, ucs2, ucs4, errors) \ 37 | do { \ 38 | if (s) while (*s) { \ 39 | utf8 c = *s++; \ 40 | if (IS_UTF8_1(c)) \ 41 | ascii++; \ 42 | else if (IS_UTF8_I(c)) { \ 43 | if (IS_UTF8_X(s[0])) \ 44 | latin1++, s++; \ 45 | else \ 46 | errors++; \ 47 | } \ 48 | else if (IS_UTF8_2(c)) { \ 49 | if (IS_UTF8_X(s[0])) \ 50 | ucs2++, s++; \ 51 | else \ 52 | errors++; \ 53 | } \ 54 | else if (IS_UTF8_3(c)) { \ 55 | if (IS_UTF8_X(s[0]) && IS_UTF8_X(s[1])) \ 56 | ucs2++, s++, s++; \ 57 | else \ 58 | errors++; \ 59 | } \ 60 | else if (IS_UTF8_4(c)) { \ 61 | if (IS_UTF8_X(s[0]) && IS_UTF8_X(s[1]) && IS_UTF8_X(s[2])) \ 62 | ucs4++, s++, s++, s++; \ 63 | else \ 64 | errors++; \ 65 | } \ 66 | else if (IS_UTF8_5(c)) { \ 67 | if (IS_UTF8_X(s[0]) && IS_UTF8_X(s[1]) && \ 68 | IS_UTF8_X(s[2]) && IS_UTF8_X(s[3])) \ 69 | ucs4++, s++, s++, s++, s++; \ 70 | else \ 71 | errors++; \ 72 | } \ 73 | else if (IS_UTF8_6(c)) { \ 74 | if (IS_UTF8_X(s[0]) && IS_UTF8_X(s[1]) && \ 75 | IS_UTF8_X(s[2]) && IS_UTF8_X(s[3]) && IS_UTF8_X(s[4])) \ 76 | ucs4++, s++, s++, s++, s++, s++; \ 77 | else \ 78 | errors++; \ 79 | } \ 80 | else \ 81 | errors++; \ 82 | } \ 83 | } while(0) 84 | 85 | #endif /* UTF8INTERNAL_H */ 86 | -------------------------------------------------------------------------------- /source/utf_convert.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2001-2004 Unicode, Inc. 3 | * 4 | * Disclaimer 5 | * 6 | * This source code is provided as is by Unicode, Inc. No claims are 7 | * made as to fitness for any particular purpose. No warranties of any 8 | * kind are expressed or implied. The recipient agrees to determine 9 | * applicability of information provided. If this file has been 10 | * purchased on magnetic or optical media from Unicode, Inc., the 11 | * sole remedy for any claim will be exchange of defective media 12 | * within 90 days of receipt. 13 | * 14 | * Limitations on Rights to Redistribute This Code 15 | * 16 | * Unicode, Inc. hereby grants the right to io_freely use the information 17 | * supplied in this file in the creation of products supporting the 18 | * Unicode Standard, and to make copies of this file in any form 19 | * for internal or external distribution as long as this notice 20 | * remains attached. 21 | */ 22 | 23 | /* --------------------------------------------------------------------- 24 | 25 | Conversions between UTF32, UTF-16, and UTF-8. Header file. 26 | 27 | Several funtions are included here, forming a complete set of 28 | conversions between the three formats. UTF-7 is not included 29 | here, but is handled in a separate source file. 30 | 31 | Each of these routines takes pointers to input buffers and output 32 | buffers. The input buffers are const. 33 | 34 | Each routine converts the text between *sourceStart and sourceEnd, 35 | putting the result into the buffer between *targetStart and 36 | targetEnd. Note: the end pointers are *after* the last item: e.g. 37 | *(sourceEnd - 1) is the last item. 38 | 39 | The return result indicates whether the conversion was successful, 40 | and if not, whether the problem was in the source or target buffers. 41 | (Only the first encountered problem is indicated.) 42 | 43 | After the conversion, *sourceStart and *targetStart are both 44 | updated to point to the end of last text successfully converted in 45 | the respective buffers. 46 | 47 | Input parameters: 48 | sourceStart - pointer to a pointer to the source buffer. 49 | The contents of this are modified on return so that 50 | it points at the next thing to be converted. 51 | targetStart - similarly, pointer to pointer to the target buffer. 52 | sourceEnd, targetEnd - respectively pointers to the ends of the 53 | two buffers, for overflow checking only. 54 | 55 | These conversion functions take a ConversionFlags argument. When this 56 | flag is set to strict, both irregular sequences and isolated surrogates 57 | will cause an error. When the flag is set to lenient, both irregular 58 | sequences and isolated surrogates are converted. 59 | 60 | Whether the flag is strict or lenient, all illegal sequences will cause 61 | an error return. This includes sequences such as: , , 62 | or in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code 63 | must check for illegal sequences. 64 | 65 | When the flag is set to lenient, characters over 0x10FFFF are converted 66 | to the replacement character; otherwise (when the flag is set to strict) 67 | they constitute an error. 68 | 69 | Output parameters: 70 | The value "sourceIllegal" is returned from some routines if the input 71 | sequence is malformed. When "sourceIllegal" is returned, the source 72 | value will point to the illegal value that caused the problem. E.g., 73 | in UTF-8 when a sequence is malformed, it points to the start of the 74 | malformed sequence. 75 | 76 | Author: Mark E. Davis, 1994. 77 | Rev History: Rick McGowan, fixes & updates May 2001. 78 | Fixes & updates, Sept 2001. 79 | 80 | ------------------------------------------------------------------------ */ 81 | 82 | /* --------------------------------------------------------------------- 83 | The following 4 definitions are compiler-specific. 84 | The C standard does not guarantee that wchar_t has at least 85 | 16 bits, so wchar_t is no less portable than unsigned short! 86 | All should be unsigned values to avoid sign extension during 87 | bit mask & shift operations. 88 | ------------------------------------------------------------------------ */ 89 | 90 | typedef unsigned long UTF32; /* at least 32 bits */ 91 | typedef unsigned short UTF16; /* at least 16 bits */ 92 | typedef unsigned char UTF8; /* typically 8 bits */ 93 | typedef unsigned char Boolean; /* 0 or 1 */ 94 | 95 | /* Some fundamental constants */ 96 | #define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD 97 | #define UNI_MAX_BMP (UTF32)0x0000FFFF 98 | #define UNI_MAX_UTF16 (UTF32)0x0010FFFF 99 | #define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF 100 | #define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF 101 | 102 | typedef enum { 103 | conversionOK, /* conversion successful */ 104 | sourceExhausted, /* partial character in source, but hit end */ 105 | targetExhausted, /* insuff. room in target for conversion */ 106 | sourceIllegal /* source sequence is illegal/malformed */ 107 | } ConversionResult; 108 | 109 | typedef enum { 110 | strictConversion = 0, 111 | lenientConversion 112 | } ConversionFlags; 113 | 114 | /* This is for C++ and does no harm in C */ 115 | #ifdef __cplusplus 116 | extern "C" { 117 | #endif 118 | 119 | ConversionResult ConvertUTF8toUTF16 ( 120 | const UTF8** sourceStart, const UTF8* sourceEnd, 121 | UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); 122 | 123 | ConversionResult ConvertUTF16toUTF8 ( 124 | const UTF16** sourceStart, const UTF16* sourceEnd, 125 | UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); 126 | 127 | ConversionResult ConvertUTF8toUTF32 ( 128 | const UTF8** sourceStart, const UTF8* sourceEnd, 129 | UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); 130 | 131 | ConversionResult ConvertUTF32toUTF8 ( 132 | const UTF32** sourceStart, const UTF32* sourceEnd, 133 | UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); 134 | 135 | ConversionResult ConvertUTF16toUTF32 ( 136 | const UTF16** sourceStart, const UTF16* sourceEnd, 137 | UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); 138 | 139 | ConversionResult ConvertUTF32toUTF16 ( 140 | const UTF32** sourceStart, const UTF32* sourceEnd, 141 | UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); 142 | 143 | Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); 144 | 145 | #ifdef __cplusplus 146 | } 147 | #endif 148 | 149 | /* --------------------------------------------------------------------- */ 150 | --------------------------------------------------------------------------------