@@ -886,3 +886,73 @@ static PyObject* connect_deltas(PyObject *self, PyObject *dstreams)
886
886
return (PyObject * )dcl ;
887
887
}
888
888
889
+
890
+ // Write using a write function, taking remaining bytes from a base buffer
891
+ // replaces the corresponding method in python
892
+ static
893
+ PyObject * apply_delta (PyObject * self , PyObject * args )
894
+ {
895
+ PyObject * pybbuf = 0 ;
896
+ PyObject * pydbuf = 0 ;
897
+ PyObject * pytbuf = 0 ;
898
+ if (!PyArg_ParseTuple (args , "OOO" , & pybbuf , & pydbuf , & pytbuf )){
899
+ PyErr_BadArgument ();
900
+ return NULL ;
901
+ }
902
+
903
+ PyObject * objects [] = { pybbuf , pydbuf , pytbuf };
904
+ assert (sizeof (objects ) / sizeof (PyObject * ) == 3 );
905
+
906
+ uint i ;
907
+ for (i = 0 ; i < 3 ; i ++ ){
908
+ if (!PyObject_CheckReadBuffer (objects [i ])){
909
+ PyErr_SetString (PyExc_ValueError , "Argument must be a buffer-compatible object, like a string, or a memory map" );
910
+ return NULL ;
911
+ }
912
+ }
913
+
914
+ Py_ssize_t lbbuf ; Py_ssize_t ldbuf ; Py_ssize_t ltbuf ;
915
+ const uchar * bbuf ; const uchar * dbuf ;
916
+ uchar * tbuf ;
917
+ PyObject_AsReadBuffer (pybbuf , (const void * * )(& bbuf ), & lbbuf );
918
+ PyObject_AsReadBuffer (pydbuf , (const void * * )(& dbuf ), & ldbuf );
919
+
920
+ if (PyObject_AsWriteBuffer (pytbuf , (void * * )(& tbuf ), & ltbuf )){
921
+ PyErr_SetString (PyExc_ValueError , "Argument 3 must be a writable buffer" );
922
+ return NULL ;
923
+ }
924
+
925
+ const uchar * data = dbuf ;
926
+ const uchar * dend = dbuf + ldbuf ;
927
+
928
+ while (data < dend )
929
+ {
930
+ const char cmd = * data ++ ;
931
+
932
+ if (cmd & 0x80 )
933
+ {
934
+ unsigned long cp_off = 0 , cp_size = 0 ;
935
+ if (cmd & 0x01 ) cp_off = * data ++ ;
936
+ if (cmd & 0x02 ) cp_off |= (* data ++ << 8 );
937
+ if (cmd & 0x04 ) cp_off |= (* data ++ << 16 );
938
+ if (cmd & 0x08 ) cp_off |= ((unsigned ) * data ++ << 24 );
939
+ if (cmd & 0x10 ) cp_size = * data ++ ;
940
+ if (cmd & 0x20 ) cp_size |= (* data ++ << 8 );
941
+ if (cmd & 0x40 ) cp_size |= (* data ++ << 16 );
942
+ if (cp_size == 0 ) cp_size = 0x10000 ;
943
+
944
+ memcpy (tbuf , bbuf + cp_off , cp_size );
945
+ tbuf += cp_size ;
946
+
947
+ } else if (cmd ) {
948
+ memcpy (tbuf , data , cmd );
949
+ tbuf += cmd ;
950
+ data += cmd ;
951
+ } else {
952
+ PyErr_SetString (PyExc_RuntimeError , "Encountered an unsupported delta cmd: 0" );
953
+ return NULL ;
954
+ }
955
+ }// END handle command opcodes
956
+
957
+ Py_RETURN_NONE ;
958
+ }
0 commit comments