Преглед изворни кода

Added incbin file hashing.

Brucey пре 5 година
родитељ
комит
69e1b880ce
3 измењених фајлова са 97 додато и 2 уклоњено
  1. 56 0
      config.bmx
  2. 23 2
      ctranslator.bmx
  3. 18 0
      hash.c

+ 56 - 0
config.bmx

@@ -55,6 +55,8 @@ Global POINTER_SIZE:Int = 4
 Global _symbols$[]=[ "..","[]",":*",":/",":+",":-",":|",":&",":~~",":shr",":shl",":sar",":mod"]
 Global _symbols_map$[]=[ "..","[]","*=","/=","+=","-=","|=","&=","^=",">>=", "<<=",">>=","%=" ]
 
+Global _fileHasher:TFileHash
+
 Function PushErr( errInfo$ )
 	_errStack.AddLast _errInfo
 	_errInfo=errInfo
@@ -665,8 +667,62 @@ Type TCallback
 	Method Callback(obj:Object) Abstract
 End Type
 
+Type TFileHash
+
+	Field statePtr:Byte Ptr
+	
+	Method Create:TFileHash()
+		statePtr = bmx_hash_createState()
+		Return Self
+	End Method
+	
+	Method CalculateHash:String(stream:TStream)
+		Const BUFFER_SIZE:Int = 8192
+	
+	
+		bmx_hash_reset(statePtr)
+		
+		Local data:Byte[BUFFER_SIZE]
+		
+		While True
+			Local read:Int = stream.Read(data, BUFFER_SIZE)
+
+			bmx_hash_update(statePtr, data, read)
+			
+			If read < BUFFER_SIZE Then
+				Exit
+			End If
+
+		Wend
+		
+		Return bmx_hash_digest(statePtr)
+		
+	End Method
+
+End Type
+
+Function CalculateFileHash:String(path:String)
+	If Not _fileHasher Then
+		_fileHasher = New TFileHash.Create()
+	End If
+
+	If FileType(path) = FILETYPE_FILE Then
+		Local stream:TStream = ReadStream(path)
+		Local fileHash:String = _fileHasher.CalculateHash(stream)
+		stream.Close()
+		
+		Return fileHash
+	End If
+	
+	Return Null
+End Function
+
 Extern
 	Function strlen_:Int(s:Byte Ptr)="strlen"
 	Function bmx_enum_next_power(char:Int, val:Long Var, ret:Long Var)
 	Function bmx_gen_hash:String(txt:String)
+	Function bmx_hash_createState:Byte Ptr()
+	Function bmx_hash_reset(state:Byte Ptr)
+	Function bmx_hash_update(state:Byte Ptr, data:Byte Ptr, length:Int)
+	Function bmx_hash_digest:String(state:Byte Ptr)
 End Extern

+ 23 - 2
ctranslator.bmx

@@ -5990,6 +5990,7 @@ End If
 		' read lines until "// ----"
 		' TODO
 		Local files:TList = New TList
+		Local hashes:TMap = New TMap
 		Local stream:TStream = ReadFile(file)
 		While True
 			Local s:String = ReadLine(stream)
@@ -5999,7 +6000,17 @@ End If
 
 			Local ind:Int = s.Find("// FILE : ")
 			If ind = 0 Then
-				files.AddLast(s[10..].Replace("~q",""))
+				Local line:String = s[10..]
+				
+				Local parts:String[] = line.Split("~t")
+				If parts.length = 1 Then
+					Return True
+				End If
+				
+				Local filename:String = parts[0].Replace("~q","")
+				Local fileHash:String = parts[1]
+				files.AddLast(filename)
+				hashes.Insert(filename, fileHash)
 			End If
 		Wend
 		stream.Close()
@@ -6042,6 +6053,15 @@ End If
 			If timestamp < FileTime(ib.path) Then
 				Return True
 			End If
+			
+			Local fileHash:String = String(hashes.ValueForKey(ib.file))
+			If Not fileHash Then
+				Return True
+			End If
+			
+			If fileHash <> CalculateFileHash(ib.path) Then
+				Return True
+			End If
 
 			' set the length, as we will need this later if we aren't loading the files now.
 			ib.length = FileSize(ib.path)
@@ -6077,7 +6097,8 @@ End If
 				app.genIncBinHeader = True
 
 				For Local ib:TIncbin = EachIn app.incbins
-					Emit "// FILE : " + Enquote(ib.file)
+					Local fileHash:String = CalculateFileHash(ib.path)
+					Emit "// FILE : " + Enquote(ib.file) + "~t" + fileHash
 				Next
 
 				Emit "// ----"

+ 18 - 0
hash.c

@@ -13,3 +13,21 @@ BBString * bmx_gen_hash(BBString * txt) {
 	snprintf(buf, 64, "0x%llx", XXH3_64bits(txt->buf, txt->length * sizeof(BBChar)));
 	return bbStringFromCString(buf);
 }
+
+XXH3_state_t * bmx_hash_createState() {
+	return XXH3_createState();
+}
+
+void bmx_hash_reset(XXH3_state_t * state) {
+	XXH3_64bits_reset(state);
+}
+
+void bmx_hash_update(XXH3_state_t * state, void * data, int length) {
+	XXH3_64bits_update(state, data, length);
+}
+
+BBString * bmx_hash_digest(XXH3_state_t * state) {
+	char * buf[64];
+	snprintf(buf, 64, "%llx", XXH3_64bits_digest(state));
+	return bbStringFromCString(buf);
+}