Skip to content

Commit

Permalink
Work some more on C StringsBuffer
Browse files Browse the repository at this point in the history
  • Loading branch information
UnknownShadow200 committed Nov 17, 2017
1 parent 4bb2892 commit ff404d3
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 34 deletions.
31 changes: 2 additions & 29 deletions src/Client/Platform.h
Expand Up @@ -8,71 +8,44 @@
Copyright 2017 ClassicalSharp | Licensed under BSD-3
*/

/* Newline for text */
extern UInt8* Platform_NewLine;
extern UInt8* Platform_NewLine; /* Newline for text */
extern UInt8 Platform_DirectorySeparator;
extern ReturnCode ReturnCode_FileShareViolation;

/* Initalises required state for this platform. */
void Platform_Init(void);
/* Releases the resources allocated for the required state. */
void Platform_Free(void);

/* Allocates a block of memory, returning NULL on failure. */
void* Platform_MemAlloc(UInt32 numBytes);
/* Frees a previously allocated block of memory. */
void* Platform_MemRealloc(void* mem, UInt32 numBytes);
void Platform_MemFree(void* mem);
/* Sets a block of memory to the given byte value. */
void Platform_MemSet(void* dst, UInt8 value, UInt32 numBytes);
/* Copies a block of non-overlapping memory. */
void Platform_MemCpy(void* dst, void* src, UInt32 numBytes);

/* Logs a message to console (if attached). Implictly puts each entry on a newline. */
void Platform_Log(STRING_PURE String* message);
/* Gets the current time, in UTC timezone. */
DateTime Platform_CurrentUTCTime(void);
/* Gets the current time, in user's local timezone. */
DateTime Platform_CurrentLocalTime(void);

/* Returns whether a directory with the given name exists. */
bool Platform_DirectoryExists(STRING_PURE String* path);
/* Creates a new directory. */
ReturnCode Platform_DirectoryCreate(STRING_PURE String* path);
/* Returns whether a file with the given name exists. */
bool Platform_FileExists(STRING_PURE String* path);

/* Creates or overwrites an existing file. */
ReturnCode Platform_FileCreate(void** file, STRING_PURE String* path);
/* Opens an existing file. */
ReturnCode Platform_FileOpen(void** file, STRING_PURE String* path, bool readOnly);
/* Reads a block of bytes from the given file, returning a platform-specific return code. */
ReturnCode Platform_FileRead(void* file, UInt8* buffer, UInt32 count, UInt32* bytesRead);
/* Writes a block of bytes to the given file, returning a platform-specific return code. */
ReturnCode Platform_FileWrite(void* file, UInt8* buffer, UInt32 count, UInt32* bytesWritten);
/* Closes the given file. */
ReturnCode Platform_FileClose(void* file);
/* Seeks / adjusts position within the file. */
ReturnCode Platform_FileSeek(void* file, Int32 offset, Int32 seekType);
/* Returns current position/offset within the file. */
UInt32 Platform_FilePosition(void* file);
/* Returns the length of the given file. */
UInt32 Platform_FileLength(void* file);

/* Blocks the calling thread for given number of milliseconds. */
void Platform_ThreadSleep(UInt32 milliseconds);

struct DrawTextArgs_;
struct Bitmap_;
/* Allocates handle for the given font. */
void Platform_MakeFont(FontDesc* desc, STRING_PURE String* fontName);
/* Frees handle for the given font. */
void Platform_FreeFont(FontDesc* desc);
/* Measures size of given text.*/
Size2D Platform_MeasureText(struct DrawTextArgs_* args);
/* Draws text onto the actively selected bitmap. */
void Platform_DrawText(struct DrawTextArgs_* args, Int32 x, Int32 y);
/* Sets the bitmap used for text drawing. */
void Platform_SetBitmap(struct Bitmap_* bmp);
/* Releases the bitmap that was used for text drawing.*/
void Platform_ReleaseBitmap(void);
#endif
44 changes: 43 additions & 1 deletion src/Client/String.c
@@ -1,6 +1,7 @@
#include "String.h"
#include "Funcs.h"
#include "ErrorHandler.h"
#include "Platform.h"

String String_Init(STRING_REF UInt8* buffer, UInt16 length, UInt16 capacity) {
String str;
Expand Down Expand Up @@ -384,6 +385,23 @@ bool Convert_TryParseBool(STRING_PURE String* str, bool* value) {

#define STRINGSBUFFER_LEN_SHIFT 10
#define STRINGSBUFFER_LEN_MASK 0x3FFUL
void StringBuffers_Init(StringsBuffer* buffer) {
buffer->Count = 0;
buffer->TextBuffer = buffer->DefaultBuffer;
buffer->FlagsBuffer = buffer->DefaultFlags;
buffer->TextBufferSize = STRINGSBUFFER_DEF_BUFFER_SIZE;
buffer->FlagsBufferElems = STRINGSBUFFER_DEF_FLAGS_ELEMS;
}

void StringsBuffer_Free(StringsBuffer* buffer) {
if (buffer->TextBufferSize > STRINGSBUFFER_DEF_BUFFER_SIZE) {
Platform_MemFree(buffer->TextBuffer);
}
if (buffer->FlagsBufferElems > STRINGSBUFFER_DEF_FLAGS_ELEMS) {
Platform_MemFree(buffer->FlagsBuffer);
}
}

void StringsBuffer_Get(StringsBuffer* buffer, UInt32 index, STRING_TRANSIENT String* text) {
String raw = StringsBuffer_UNSAFE_Get(buffer, index);
String_Clear(text);
Expand All @@ -393,8 +411,32 @@ void StringsBuffer_Get(StringsBuffer* buffer, UInt32 index, STRING_TRANSIENT Str
String StringsBuffer_UNSAFE_Get(StringsBuffer* buffer, UInt32 index) {
if (index >= buffer->Count) ErrorHandler_Fail("Tried to get String past StringsBuffer end");

UInt32 flags = buffer->FlagsBuffer[index];
UInt32 flags = buffer->FlagsBuffer[index];
UInt32 offset = flags >> STRINGSBUFFER_LEN_SHIFT;
UInt32 len = flags & STRINGSBUFFER_LEN_MASK;
return String_Init(&buffer->TextBuffer[offset], (UInt16)len, (UInt16)len);
}

void StringsBuffer_Remove(StringsBuffer* buffer, UInt32 index) {
if (index >= buffer->Count) ErrorHandler_Fail("Tried to remove String past StringsBuffer end");

UInt32 flags = buffer->FlagsBuffer[index];
UInt32 offset = flags >> STRINGSBUFFER_LEN_SHIFT;
UInt32 len = flags & STRINGSBUFFER_LEN_MASK;

UInt32 lastFlags = buffer->FlagsBuffer[buffer->Count - 1];
UInt32 lastOffset = lastFlags >> STRINGSBUFFER_LEN_SHIFT;
UInt32 lastLen = lastFlags & STRINGSBUFFER_LEN_MASK;

/* Imagine buffer is this: XXYYYYZZZ, and want to delete X */
/* Start points to first character of Y */
/* End points to last character of Z */
UInt32 i, start = offset + len, end = lastOffset + lastLen;
for (i = start; i < end; i++) {
buffer->TextBuffer[i - len] = buffer->TextBuffer[i];
}
for (i = index; i < buffer->Count; i++) {
buffer->FlagsBuffer[i] = buffer->FlagsBuffer[i + 1];
}
buffer->Count--;
}
8 changes: 5 additions & 3 deletions src/Client/String.h
Expand Up @@ -72,14 +72,16 @@ bool Convert_TryParseUInt16(STRING_PURE String* str, UInt16* value);
bool Convert_TryParseReal32(STRING_PURE String* str, Real32* value);
bool Convert_TryParseBool(STRING_PURE String* str, bool* value);

/* todo use a single byte array for all strings, each 'string' is 22 bits offsrt, 10 bits length into this array. */
/* means resizing is expensive tho*/
#define STRINGSBUFFER_DEF_BUFFER_SIZE 4096
#define STRINGSBUFFER_DEF_FLAGS_ELEMS 256
typedef struct StringsBuffer_ {
UInt8* TextBuffer;
UInt32 TextBufferSize;
UInt32* FlagsBuffer;
UInt32 FlagsBufferSize;
UInt32 FlagsBufferElems;
UInt32 Count;
UInt8 DefaultBuffer[STRINGSBUFFER_DEF_BUFFER_SIZE];
UInt32 DefaultFlags[STRINGSBUFFER_DEF_FLAGS_ELEMS];
} StringsBuffer;

void StringBuffers_Init(StringsBuffer* buffer);
Expand Down
9 changes: 8 additions & 1 deletion src/Client/WinPlatform.c
Expand Up @@ -61,6 +61,10 @@ void* Platform_MemAlloc(UInt32 numBytes) {
return HeapAlloc(heap, 0, numBytes);
}

void* Platform_MemRealloc(void* mem, UInt32 numBytes) {
return HeapReAlloc(heap, 0, mem, numBytes);
}

void Platform_MemFree(void* mem) {
HeapFree(heap, 0, mem);
}
Expand Down Expand Up @@ -188,13 +192,15 @@ void Platform_ThreadSleep(UInt32 milliseconds) {
}


void Platform_MakeFont(FontDesc* desc) {
void Platform_MakeFont(FontDesc* desc, STRING_PURE String* fontName) {
LOGFONTA font = { 0 };
font.lfHeight = -Math_Ceil(desc->Size * GetDeviceCaps(hdc, LOGPIXELSY) / 72.0f);
font.lfUnderline = desc->Style == FONT_STYLE_UNDERLINE;
font.lfWeight = desc->Style == FONT_STYLE_BOLD ? FW_BOLD : FW_NORMAL;
font.lfQuality = ANTIALIASED_QUALITY;

String dstName = String_Init(font.lfFaceName, 0, LF_FACESIZE);
String_AppendString(&dstName, fontName);
desc->Handle = CreateFontIndirectA(&font);
if (desc->Handle == NULL) ErrorHandler_Fail("Creating font handle failed");
}
Expand All @@ -204,6 +210,7 @@ void Platform_FreeFont(FontDesc* desc) {
desc->Handle = NULL;
}

/* TODO: Associate Font with device */
Size2D Platform_MeasureText(struct DrawTextArgs_* args) {
HDC hDC = GetDC(NULL);
RECT r = { 0 };
Expand Down

0 comments on commit ff404d3

Please sign in to comment.