Skip to content

Instantly share code, notes, and snippets.

@kev009
Created November 25, 2010 05:48
Show Gist options
  • Save kev009/714966 to your computer and use it in GitHub Desktop.
Save kev009/714966 to your computer and use it in GitHub Desktop.
Minecraft strings
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <pthread.h>
#include <event2/buffer.h>
#include "craftd-config.h"
#include "util.h"
/**
* Check if str is valid MC UTF-8, nonzero otherwise
* @param str string to check
* @return 0 if valid, nonzero otherwise
*/
int
ismc_utf8(const char *const str)
{
const char *const MC_UTF8 =
"\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_'abcdefgh"
"ijklmnopqrstuvwxyz{|}~.ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø×.áíóúñѪº¿®¬½¼¡«»";
if( strspn(str, MC_UTF8) == strlen(str) )
return 0;
return EBADMSG;
}
/*
* MC Strings always have known lengths. Take advantage of this and try to
* create infallible strings. Critique and review of this code needed.
*/
/**
* Create an mcstring from a slen and character array. The character array does
* not need to be null terminated, but slen MUST EQUAL the number of characters
* not including a NUL terminator. strlen provides this behavior for internal
* C strings.
*
* If the string needs to be reader/writer locked for use in reentrant
* functions, pass in an initialized rwlock. The lock and the input string
* arg need to be manually freed when finished.
*
* @param slen string length, not including NUL terminator
* @param strptr input string
* @param rwlock a reader/writer lock if necessary
* @return a ptr to an mcstring structure or null
*/
mcstring_t *
mcstring_create(int16_t slen, char *strptr, pthread_rwlock_t rwlock)
{
if (slen > MC_MAXSTRING)
goto err; // LOG bad string
char *strin;
strin = (char *)Malloc(slen+1);
/* NUL terminate the end. If strnlen doesn't match slen, something
* strange is going on with the client.
*/
strin[slen] = '\0';
memcpy(strin, strptr, slen);
if (strlen(strin) != slen)
goto err; // LOG bad string
if (!ismc_utf8(strin))
goto err; // LOG bad string
mcstring_t *mcstring;
mcstring = (mcstring_t *)Malloc(sizeof(mcstring_t));
mcstring->slen = slen;
mcstring->str = strin;
mcstring->rwlock = rwlock;
/* return a valid mcstring construction */
return mcstring;
err:
if(strin)
free(strin);
return NULL;
}
//TODO mcstring cat
/**
* Free an mcstring instance.
*
* Make sure to destroy the rwlock first if it exists.
*
* @param mcstring string to free
*/
void
mcstring_free(mcstring_t * mcstring)
{
free(mcstring->str);
free(mcstring);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment