/** * @file staticstring.c * @brief Implements the staticstring subsystem. */ #include #include #include akerr_ErrorContext *akgl_string_initialize(akgl_String *obj, char *init) { PREPARE_ERROR(errctx); FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "Attempted to initialize NULL string reference"); if ( init != NULL ) { PASS(errctx, aksl_strncpy((char *)&obj->data, sizeof(obj->data), init, sizeof(obj->data) - 1)); } else { // sizeof(obj->data), not sizeof(akgl_String). `data` starts after the // `refcount` in front of it, so zeroing the size of the whole struct // from the start of the buffer ran four bytes past the end of the // object -- into the next pool slot's refcount, which is what makes a // free slot look claimed or a claimed one look free. memset(&obj->data, 0x00, sizeof(obj->data)); } obj->refcount = 1; SUCCEED_RETURN(errctx); } akerr_ErrorContext *akgl_string_copy(akgl_String *src, akgl_String *dest, int count) { PREPARE_ERROR(errctx); FAIL_ZERO_RETURN(errctx, src, AKERR_NULLPOINTER, "NULL argument"); FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "NULL argument"); if ( count == 0 ) { count = AKGL_MAX_STRING_LENGTH; } // Both buffers are exactly AKGL_MAX_STRING_LENGTH bytes, so a larger count // walks off the end of two pool slots at once. Refused rather than // documented, which is what it used to be. FAIL_NONZERO_RETURN( errctx, ((count < 0) || (count > AKGL_MAX_STRING_LENGTH)), AKERR_OUTOFBOUNDS, "Copy count %d is outside 0..%d", count, AKGL_MAX_STRING_LENGTH); PASS(errctx, aksl_strncpy((char *)&dest->data, sizeof(dest->data), (char *)&src->data, count)); SUCCEED_RETURN(errctx); }