/* We use the garbage collector's feature to "pin" an Object at a * particular memory location to allow C code to write directly into the * contets of a Ruby String (actually, a CharArray, which provides the * storage for String). Since any method on String that mutates self may * cause a new CharArray to be created, we always check whether the * String is pinned and update the RString structure unconditionally. */ void ensure_pinned(NativeMethodEnvironment* env, String* string, RString* rstring) { CharArray* ca = string->data(); size_t byte_size = ca->size(); if(!ca->pinned_p()) { ca = CharArray::create_pinned(env->state(), byte_size); memcpy(ca->raw_bytes(), string->byte_address(), byte_size); string->data(env->state(), ca); } char* ptr = reinterpret_cast<char*>(ca->raw_bytes()); ptr[byte_size-1] = 0; rstring->dmwmb = rstring->ptr = ptr; rstring->len = string->size(); rstring->aux.capa = byte_size; rstring->aux.shared = Qfalse; }