public void writeRawULong(long val, int bits) throws IOException {
        if (bits == 0) return;
        if (!ensureSize(bits)) throw new IOException("Memory Allocate Error");
        val &= MASK32[bits];
        totalBits += bits;
        while (bits > 0) {
            if (outBits == 0) {
                if (bits < BITS_PER_BLURB) {
                    buffer[outBlurbs] = (byte) val;
                    outBits = bits;
                    break;
                } else if (bits == BITS_PER_BLURB) {
                    buffer[outBlurbs++] = (byte) val;
                    break;
                } else {
                    int k = bits - BITS_PER_BLURB;
                    buffer[outBlurbs++] = (byte) (val >> k);
                    
                    // we know k < 64 so no need to protect against the gcc bug mentioned above
                    val &= (~(0xffffffffffffffffL << k));
                    bits -= BITS_PER_BLURB;
                }
            } else {
                int n = Math.min(BITS_PER_BLURB - outBits, bits);
                int k = bits - n;
                buffer[outBlurbs] <<= n;
                buffer[outBlurbs] |= (val >> k);
                
                // we know n > 0 so k < 64 so no need to protect against the gcc bug mentioned above
                val &= (~(0xffffffffffffffffL << k));
                bits -= n;
                outBits += n;
                if (outBits == BITS_PER_BLURB) {
                    outBlurbs++;
                    outBits = 0;
                }
            }
        }
    }