#include "tstring.h" int GetGlyphByteWidth(const char* glyph); void TStringCopyGlyph(const char* glyph, int length, TString* string); struct __tstring { char* Characters; int Length; int ByteCount; int Capacity; }; TString* TStringCreate(void) { TString* string = malloc(sizeof(TString)); string->Characters = calloc(DEFAULT_TSTRING_BYTE_BUFFER, sizeof(char)); string->Capacity = DEFAULT_TSTRING_BYTE_BUFFER; string->ByteCount = 0; string->Length = 0; return string; } int TStringLength(const TString* string) { if (!string) return - 1; return string->Length; } void TStringAppendText(const char* text, TString* string) { int totalLength = strlen(text); int glyphLength = GetGlyphByteWidth(text); //If the two lengths are the same then that means we have a single character. //Simply append it to the list and return. if (totalLength == glyphLength) { TStringCopyGlyph(text, glyphLength, string); return; } //If we've made it here, than that means we have a full on string of characters. for(int i = 0; i < totalLength;) { TStringCopyGlyph(&text[i], glyphLength, string); i += glyphLength; glyphLength = GetGlyphByteWidth(&text[i]); } } char* TStringGetString(const TString* string) { if (!string) return NULL; char* text = calloc(string->ByteCount + 1, sizeof(char)); if (!text) { fprintf(stderr, "Failed to calloc memory for TString text. %s.\n", strerror(errno)); return NULL; } memcpy(text, string->Characters, string->ByteCount); return text; } void TStringGetGlyph(int index, char buffer[8], const TString* string) { if (!buffer || !string) return; memset(buffer, '\0', sizeof *buffer); int glyphCount = 0; for(int i = 0; i < string->ByteCount;) { int glyphWidth = GetGlyphByteWidth(&string->Characters[i]); if (glyphCount == index) { memcpy(buffer, &string->Characters[i], glyphWidth); return; } glyphCount++; i += glyphWidth; } } void TStringFree(TString* string) { if (!string) return; if (string->Characters) free(string->Characters); free(string); } int GetGlyphByteWidth(const char* glyph) { // printf("Bytes for '%s': ", glyph); // for(size_t i = 0; i < strlen(glyph); i++) { // printf("%02X ", 0xFF & glyph[i]); // } // printf("\n"); if ((*glyph & 0x80) == 0) { return 1; } else if ((*glyph & 0xE0) == 0xC0) { return 2; } else if ((*glyph & 0xF0) == 0xE0) { return 3; } else if ((*glyph & 0xF8) == 0xF0) { return 4; } return -1; } void TStringCopyGlyph(const char* glyph, int length, TString* string) { if (length < 1) return; if (string->ByteCount + length > string->Capacity) { char* buffer = realloc(string->Characters, string->Capacity * 2); if (!buffer) { fprintf(stderr, "Failed to realloc memory TString. %s.\n", strerror(errno)); return; } string->Characters = buffer; string->Capacity *= 2; } memcpy(&string->Characters[string->ByteCount], glyph, length); string->ByteCount += length; string->Length++; } void TStringPrintDetails(const TString* string) { if (!string) return; printf("Length: %d Size: %d byte(s) Capacity: %d bytes\n", string->Length, string->ByteCount, string->Capacity); printf("%s", TStringGetString(string)); printf("\n"); }