Exemplo n.º 1
0
uint32_t LLCALL_C io_hash_path(char const *path, char const **out_end)
{
    if (path == NULL)
    {
        if (out_end) *out_end = NULL;
        return 0;
    }

    uint32_t    cp   = 0;
    uint32_t    cp2  = 0;
    uint32_t    cp3  = 0;
    uint32_t    hash = 0;
    char const *iter = next_codepoint(path, cp);
    while (cp != 0)
    {
        cp2    = UTF8_TOUPPER(cp);
        cp3    = cp != '\\' ? cp2 : '/';
        hash   = ROTATE_LEFT(hash, 7) + cp3;
        iter   = next_codepoint(iter, cp);
    }
    if (out_end)
    {   
       *out_end = iter + 1;
    }
    return hash;
}
Exemplo n.º 2
0
void gui::measure_string(gui::bitmap_font_t const *font, char const *str, size_t *out_w, size_t *out_h)
{
    if (str != NULL)
    {
        size_t   l = 0; // length, in characters
        size_t   w = 0; // total width, in pixels
        size_t   h = 0; // total height, in pixels
        uint32_t c = 0; // current  UTF-8 codepoint, 0xFFFFFFFFU = invalid
        uint32_t p = 0; // previous UTF-8 codepoint, 0xFFFFFFFFU = invalid
        uint32_t const  m = uint32_t(font->BucketCount - 1);
        char const     *n = next_codepoint(str, c);
        while (c != 0)
        {
            uint32_t bucket = uint32_hash(c) & m;
            uint32_t const *table = font->GTable[bucket];
            uint32_t const  count = font->GTable[bucket][FONT_SIZE_INDEX];
            for (size_t  i  = FONT_CODEPOINT_OFFSET; i < FONT_CODEPOINT_OFFSET + count; ++i)
            {
                if (table[i] == c)
                {
                    size_t gi = table[i];   // the index in into font->Glyphs.
                    w += advance_x(font, p, c, font->Glyphs[gi].AdvanceX);
                    break;
                }
            }
            if (c == '\n') h += font->LineHeight;
            p = c;
            n = next_codepoint(n, c);
            l++;
        }
        if (l > 0) h += font->LineHeight;
        if (out_w)*out_w = w;
        if (out_h)*out_h = h;
    }
    else
    {
        if (out_w) *out_w = 0;
        if (out_h) *out_h = 0;
    }
}
Exemplo n.º 3
0
/* 
   hash a string of the specified length. The string does not need to be
   null terminated 

   hash alghorithm changed to FNV1 by [email protected] (Simo Sorce).
   see http://www.isthe.com/chongo/tech/comp/fnv/index.html for a
   discussion on Fowler / Noll / Vo (FNV) Hash by one of it's authors
*/
uint32_t pvfs_name_hash(const char *key, size_t length)
{
	const uint32_t fnv1_prime = 0x01000193;
	const uint32_t fnv1_init = 0xa6b93095;
	uint32_t value = fnv1_init;

	while (*key && length--) {
		size_t c_size;
		codepoint_t c = next_codepoint(key, &c_size);
		c = toupper_m(c);
                value *= fnv1_prime;
                value ^= (uint32_t)c;
		key += c_size;
        }

	return value;
}
Exemplo n.º 4
0
/*
 See if a filename is a legal long filename.
 A filename ending in a '.' is not legal unless it's "." or "..". JRA.
*/
static bool is_legal_name(struct pvfs_mangle_context *ctx, const char *name)
{
	while (*name) {
		size_t c_size;
		codepoint_t c = next_codepoint(name, &c_size);
		if (c == INVALID_CODEPOINT) {
			return false;
		}
		/* all high chars are OK */
		if (c >= 128) {
			name += c_size;
			continue;
		}
		if (FLAG_CHECK(c, FLAG_ILLEGAL)) {
			return false;
		}
		name += c_size;
	}

	return true;
}
Exemplo n.º 5
0
/**
 String replace.
 NOTE: oldc and newc must be 7 bit characters
**/
void string_replace( char *s, char oldc, char newc )
{
	char *p;

	/* this is quite a common operation, so we want it to be
	   fast. We optimise for the ascii case, knowing that all our
	   supported multi-byte character sets are ascii-compatible
	   (ie. they match for the first 128 chars) */

	for (p = s; *p; p++) {
		if (*p & 0x80) /* mb string - slow path. */
			break;
		if (*p == oldc) {
			*p = newc;
		}
	}

	if (!*p)
		return;

	/* Slow (mb) path. */
#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
	/* With compose characters we must restart from the beginning. JRA. */
	p = s;
#endif

	while (*p) {
		size_t c_size;
		next_codepoint(p, &c_size);

		if (c_size == 1) {
			if (*p == oldc) {
				*p = newc;
			}
		}
		p += c_size;
	}
}
Exemplo n.º 6
0
/* Will decode an array of utf-8-encoded bytes, buff, into an array of Unicode
 * code points, and return a pointer to the array. Requires the number of bytes
 * in buff, passed as in_len. Writes the length of the buffer returned into
 * the address of out_len.
 */
UNICHAR * utf8_decode_buffer(const char * buff,
                             size_t in_len,
                             size_t *out_len) {
  size_t bytes_left = in_len;
  UNICHAR target;
  UNICHAR * temp;
  UNICHAR * out_buffer;
  size_t written = 0;

#ifdef UNICODEC_DEBUG
  fprintf(stderr, "in utf8_decode_buffer(%p, %lu, %p):\n",
          buff, in_len, out_len);
#endif

  temp = malloc(sizeof(UNICHAR) * in_len);
  while(bytes_left > 0) {

#ifdef UNICODEC_DEBUG
    fprintf(stderr, "  bytes_left: %lu\n", bytes_left);
#endif
    
    target = next_codepoint(&(buff[in_len-bytes_left]),
                            &bytes_left);
#ifdef UNICODEC_DEBUG
    fprintf(stderr, "  decoded: %u; bytes_left: %lu\n", target, bytes_left);
#endif
    temp[written] = target;
    ++written;
  }

  out_buffer = malloc(sizeof(UNICHAR) * written);
  for(size_t n = 0; n < written; ++n)
    out_buffer[n] = temp[n];
  free(temp);
  *out_len = written;

  return(out_buffer);
}
Exemplo n.º 7
0
bool set_conn_connectpath(connection_struct *conn, const char *connectpath)
{
	char *destname;
	char *d;
	const char *s = connectpath;
        bool start_of_name_component = true;

	if (connectpath == NULL || connectpath[0] == '\0') {
		return false;
	}

	/* Allocate for strlen + '\0' + possible leading '/' */
	destname = SMB_MALLOC(strlen(connectpath) + 2);
	if (!destname) {
		return false;
	}
	d = destname;

	*d++ = '/'; /* Always start with root. */

	while (*s) {
		if (*s == '/') {
			/* Eat multiple '/' */
			while (*s == '/') {
                                s++;
                        }
			if ((d > destname + 1) && (*s != '\0')) {
				*d++ = '/';
			}
			start_of_name_component = True;
			continue;
		}

		if (start_of_name_component) {
			if ((s[0] == '.') && (s[1] == '.') && (s[2] == '/' || s[2] == '\0')) {
				/* Uh oh - "/../" or "/..\0" ! */

				/* Go past the ../ or .. */
				if (s[2] == '/') {
					s += 3;
				} else {
					s += 2; /* Go past the .. */
				}

				/* If  we just added a '/' - delete it */
				if ((d > destname) && (*(d-1) == '/')) {
					*(d-1) = '\0';
					d--;
				}

				/* Are we at the start ? Can't go back further if so. */
				if (d <= destname) {
					*d++ = '/'; /* Can't delete root */
					continue;
				}
				/* Go back one level... */
				/* Decrement d first as d points to the *next* char to write into. */
				for (d--; d > destname; d--) {
					if (*d == '/') {
						break;
					}
				}
				/* We're still at the start of a name component, just the previous one. */
				continue;
			} else if ((s[0] == '.') && ((s[1] == '\0') || s[1] == '/')) {
				/* Component of pathname can't be "." only - skip the '.' . */
				if (s[1] == '/') {
					s += 2;
				} else {
					s++;
				}
				continue;
			}
		}

		if (!(*s & 0x80)) {
			*d++ = *s++;
		} else {
			size_t siz;
			/* Get the size of the next MB character. */
			next_codepoint(s,&siz);
			switch(siz) {
				case 5:
					*d++ = *s++;
					/*fall through*/
				case 4:
					*d++ = *s++;
					/*fall through*/
				case 3:
					*d++ = *s++;
					/*fall through*/
				case 2:
					*d++ = *s++;
					/*fall through*/
				case 1:
					*d++ = *s++;
					break;
				default:
					break;
			}
		}
		start_of_name_component = false;
	}
	*d = '\0';

	/* And must not end in '/' */
	if (d > destname + 1 && (*(d-1) == '/')) {
		*(d-1) = '\0';
	}

	DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n",
		lp_servicename(SNUM(conn)), destname ));

	string_set(&conn->connectpath, destname);
	SAFE_FREE(destname);
	return true;
}