mercurial/cext/mpatch.c
changeset 39991 77492c10a35b
parent 36620 186c6df3a373
child 39992 ec3c06a1c554
equal deleted inserted replaced
39990:a91398dc73ab 39991:77492c10a35b
    70 
    70 
    71 static PyObject *patches(PyObject *self, PyObject *args)
    71 static PyObject *patches(PyObject *self, PyObject *args)
    72 {
    72 {
    73 	PyObject *text, *bins, *result;
    73 	PyObject *text, *bins, *result;
    74 	struct mpatch_flist *patch;
    74 	struct mpatch_flist *patch;
    75 	const char *in;
    75 	Py_buffer buffer;
    76 	int r = 0;
    76 	int r = 0;
    77 	char *out;
    77 	char *out;
    78 	Py_ssize_t len, outlen, inlen;
    78 	Py_ssize_t len, outlen;
    79 
    79 
    80 	if (!PyArg_ParseTuple(args, "OO:mpatch", &text, &bins))
    80 	if (!PyArg_ParseTuple(args, "OO:mpatch", &text, &bins))
    81 		return NULL;
    81 		return NULL;
    82 
    82 
    83 	len = PyList_Size(bins);
    83 	len = PyList_Size(bins);
    85 		/* nothing to do */
    85 		/* nothing to do */
    86 		Py_INCREF(text);
    86 		Py_INCREF(text);
    87 		return text;
    87 		return text;
    88 	}
    88 	}
    89 
    89 
    90 	if (PyObject_AsCharBuffer(text, &in, &inlen))
    90 	if (PyObject_GetBuffer(text, &buffer, PyBUF_CONTIG_RO)) {
    91 		return NULL;
    91 		return NULL;
       
    92 	}
    92 
    93 
    93 	patch = mpatch_fold(bins, cpygetitem, 0, len);
    94 	patch = mpatch_fold(bins, cpygetitem, 0, len);
    94 	if (!patch) { /* error already set or memory error */
    95 	if (!patch) { /* error already set or memory error */
    95 		if (!PyErr_Occurred())
    96 		if (!PyErr_Occurred())
    96 			PyErr_NoMemory();
    97 			PyErr_NoMemory();
    97 		return NULL;
    98 		result = NULL;
    98 	}
    99 		goto cleanup;
    99 
   100 	}
   100 	outlen = mpatch_calcsize(inlen, patch);
   101 
       
   102 	outlen = mpatch_calcsize(buffer.len, patch);
   101 	if (outlen < 0) {
   103 	if (outlen < 0) {
   102 		r = (int)outlen;
   104 		r = (int)outlen;
   103 		result = NULL;
   105 		result = NULL;
   104 		goto cleanup;
   106 		goto cleanup;
   105 	}
   107 	}
   110 	}
   112 	}
   111 	out = PyBytes_AsString(result);
   113 	out = PyBytes_AsString(result);
   112 	/* clang-format off */
   114 	/* clang-format off */
   113 	{
   115 	{
   114 		Py_BEGIN_ALLOW_THREADS
   116 		Py_BEGIN_ALLOW_THREADS
   115 		r = mpatch_apply(out, in, inlen, patch);
   117 		r = mpatch_apply(out, buffer.buf, buffer.len, patch);
   116 		Py_END_ALLOW_THREADS
   118 		Py_END_ALLOW_THREADS
   117 	}
   119 	}
   118 	/* clang-format on */
   120 	/* clang-format on */
   119 	if (r < 0) {
   121 	if (r < 0) {
   120 		Py_DECREF(result);
   122 		Py_DECREF(result);
   121 		result = NULL;
   123 		result = NULL;
   122 	}
   124 	}
   123 cleanup:
   125 cleanup:
   124 	mpatch_lfree(patch);
   126 	mpatch_lfree(patch);
       
   127 	PyBuffer_Release(&buffer);
   125 	if (!result && !PyErr_Occurred())
   128 	if (!result && !PyErr_Occurred())
   126 		setpyerr(r);
   129 		setpyerr(r);
   127 	return result;
   130 	return result;
   128 }
   131 }
   129 
   132