bool MC_StringIsValid (MCString self) { assert(self); for (size_t i = 0, ie = CD_StringLength(self); i < ie; i++) { bool has = false; CDString* ch = CD_CharAt(self, i); for (size_t h = 0, he = cd_UTF8_strlen(MCCharset); h < he; h++) { const char* che = &MCCharset[cd_UTF8_offset(MCCharset, h)]; if (strncmp(CD_StringContent(ch), che, CD_StringSize(ch)) == 0) { has = true; break; } } if (!has && !(strncmp(CD_StringContent(ch), "§", 2) == 0 && i < ie - 2)) { CD_DestroyString(ch); return false; } CD_DestroyString(ch); } return true; }
static void cd_ConsoleLog (int priority, const char* format, ...) { /* Return on MASKed log priorities */ if (LOG_MASK(priority) & cd_mask) { return; } static const char* names[] = { "EMERG", "ALERT", "CRIT", "ERR", "WARNING", "NOTICE", "INFO", "DEBUG" }; va_list ap; va_start(ap, format); CDString* priorityBuffer; CDString* messageBuffer = CD_CreateStringFromFormatList(format, ap); if (priority >= (sizeof(names) / sizeof(char*)) || priority < 0) { priorityBuffer = CD_CreateStringFromCString("UNKNOWN"); } else { priorityBuffer = CD_CreateStringFromCString(names[priority]); } printf("%s: %s\n", CD_StringContent(priorityBuffer), CD_StringContent(messageBuffer)); fflush(stdout); CD_DestroyString(priorityBuffer); CD_DestroyString(messageBuffer); va_end(ap); }
void cdtest_String_UTF8_charAt (void* data) { CDString* test = CD_CreateStringFromCString("ƧÐ"); CDString* ch = CD_CharAt(test, 1); tt_assert(CD_StringIsEqual(ch, "§")); end: { CD_DestroyString(test); CD_DestroyString(ch); } }
void cdtest_String_Minecraft_sanitize (void* data) { CDString* string = CD_CreateStringFromCString("æßðđ¼½¬²³æðđ]}»”¢“}¹²³þæßł@»ł”##æðþŋŋŋ§2ŋŋŋł€¶®ÐJª§&<©>‘ŁØ&ØΩ§3"); CDString* sanitized = MC_StringSanitize(string); tt_assert(CD_StringIsEqual(sanitized, "æ???¼½¬??æ??]}»???}????æ??@»??##æ?????§2??????®?Jª§&<?>??Ø&Ø?")); end: { CD_DestroyString(string); CD_DestroyString(sanitized); } }
void cdtest_String_Minecraft_valid (void* data) { CDString* invalid = CD_CreateStringFromCString("æßðđ¼½¬²³æðđ]}»”¢“}¹²³þæßł@»ł”##æðþŋŋŋ§2ŋŋŋł€¶®ÐJª§&<©>‘ŁØ&ØΩ§3"); CDString* valid = CD_CreateStringFromCString("æ???¼½¬??æ??]}»???}????æ??@»??##æ?????§2??????®?Jª§&<?>??Ø&Ø?"); tt_assert(MC_StringIsValid(invalid) == false); tt_assert(MC_StringIsValid(valid) == true); end: { CD_DestroyString(invalid); CD_DestroyString(valid); } }
void cdadmin_DestroyTicket (CDATicket* self) { if (self->content) { CD_DestroyString(self->content); } CD_free(self); }
void MC_DestroyData (MCData* self) { // Destroy the bstring, the other types lay on the stack if (self->type == MCTypeString) { CD_DestroyString(self->data.S); } CD_free(self); }
void cdtest_String_UTF8_length (void* data) { CDString* test = CD_CreateStringFromCString("ƧÐ"); tt_int_op(CD_StringLength(test), ==, 3); tt_int_op(CD_StringSize(test), ==, 6); end: { CD_DestroyString(test); } }
void cdtest_String_fromBuffer (void* data) { const char* test = "lol wut"; CDString* string = CD_CreateStringFromBuffer(test, 3); tt_int_op(CD_StringLength(string), ==, 3); end: { CD_DestroyString(string); } }
void CD_BufferAddString (CDBuffer* self, CDString* data) { CDString* sanitized = MC_StringSanitize(data); MCShort size = htons(CD_StringSize(sanitized)); evbuffer_add(self->raw, &size, MCShortSize); evbuffer_add(self->raw, CD_StringContent(sanitized), CD_StringSize(sanitized)); CD_DestroyString(sanitized); }
MCString MC_StringSanitize (MCString self) { CDString* result = CD_CreateString(); assert(self); for (size_t i = 0, ie = CD_StringLength(self); i < ie; i++) { bool has = false; CDString* ch = CD_CharAt(self, i); for (size_t h = 0, he = cd_UTF8_strlen(MCCharset); h < he; h++) { const char* che = &MCCharset[cd_UTF8_offset(MCCharset, h)]; if (strncmp(CD_StringContent(ch), che, CD_StringSize(ch)) == 0) { has = true; break; } } if (i == ie - 2 && strncmp(CD_StringContent(ch), "§", 2) == 0){ CD_DestroyString(ch); break; } if (has || strncmp(CD_StringContent(ch), "§", 2) == 0) { CD_AppendString(result, ch); } else { CD_AppendCString(result, "?"); } CD_DestroyString(ch); } cd_UpdateLength(self); return result; }
MCString MC_StringColorRange (MCString self, MCStringColor color, size_t a, size_t b) { if (self->external) { CDString* tmp = self; self = CD_CloneString(tmp); CD_DestroyString(tmp); } CDString* start = CD_CreateStringFromFormat("§%x", color); CDString* end = CD_CreateStringFromCString(MC_COLOR_WHITE); assert(self); assert(a < b); assert(a >= 0 && b <= CD_StringLength(self)); CD_InsertString(self, end, b); CD_InsertString(self, start, a); CD_DestroyString(start); CD_DestroyString(end); return self; }
CDString* CD_PrependCString (CDString* self, const char* append) { assert(self); assert(append); cd_MakeStringInternal(self); CDString* tmp = CD_CreateStringFromCString(append); if (!CD_PrependString(self, tmp)) { self = NULL; } CD_DestroyString(tmp); return self; }
CDString* CD_AppendStringAndClean (CDString* self, CDString* append) { assert(self); assert(append); cd_MakeStringInternal(self); if (binsert(self->raw, self->raw->slen, append->raw, '\0') == BSTR_OK) { cd_UpdateLength(self); } else { self = NULL; } CD_DestroyString(append); return self; }
static bool cdadmin_HandleChat (CDServer* server, CDPlayer* player, CDString* message) { if (!player->username) { return false; } CDString* name = cdadmin_ColoredNick(player); SLOG(server, LOG_NOTICE, "<%s> %s", CD_StringContent(player->username), CD_StringContent(message)); CD_ServerBroadcast(server, CD_CreateStringFromFormat("<%s> %s", CD_StringContent(name), CD_StringContent(message))); // TODO: testing/WIP? //CD_ServerBroadcast(server, CD_CreateStringFromCString(MCCharset)); CD_DestroyString(name); return false; }
void SV_DestroyString (SVString self) { CD_DestroyString(self); }
static void cd_StaticRequest (struct evhttp_request* request, CDServer* server) { int error = HTTP_OK; const char* message = "OK"; const char* uri = evhttp_request_get_uri(request); struct evhttp_uri* decoded = evhttp_uri_parse(uri); if (evhttp_request_get_command(request) != EVHTTP_REQ_GET) { error = HTTP_BADMETHOD; message = "Invalid request method"; goto end; } if (!decoded || strstr(evhttp_uri_get_path(decoded), "..")) { error = HTTP_BADREQUEST; message = "Bad request"; goto end; } DO { CDString* path = CD_CreateStringFromFormat("%s/%s", server->config->cache.httpd.root, evhttp_uri_get_path(decoded) ? evhttp_uri_get_path(decoded) : "index.html"); if (CD_IsDirectory(CD_StringContent(path))) { CD_AppendCString(path, "/index.html"); } if (!CD_IsReadable(CD_StringContent(path))) { error = HTTP_NOTFOUND; message = "File not found"; CD_DestroyString(path); goto end; } struct evbuffer* buffer = evbuffer_new(); int fd = open(CD_StringContent(path), O_RDONLY); evhttp_add_header(evhttp_request_get_output_headers(request), "Content-Type", cd_GuessContentType(CD_StringContent(path))); evbuffer_add_file(buffer, fd, 0, CD_FileSize(CD_StringContent(path))); evhttp_send_reply(request, HTTP_OK, "OK", buffer); evbuffer_free(buffer); CD_DestroyString(path); } end: { if (decoded) { evhttp_uri_free(decoded); } if (error != HTTP_OK) { evhttp_send_error(request, error, message); } } }
void MC_DestroyString (MCString self) { CD_DestroyString(self); }