/// <summary> /// Add string to the end of the loc file /// </summary> /// <param name="stringId"></param> /// <param name="content"></param> public void AddString(string stringId, string content) { uint hashId = 0; if (stringId.Length > 2 && stringId[0] == '0' && stringId[1] == 'x') { try { hashId = UInt32.Parse(stringId.Substring(2), System.Globalization.NumberStyles.AllowHexSpecifier); } catch (Exception e) { Console.WriteLine("Error! invalid string key:'{0}'", stringId); throw e; } } else { hashId = HashHelper.HashString(stringId); } UInt16 sz = (UInt16)((content.Length * 2) + 2 + 4 + 4); // 2:size info 4:hashId 4 min zero bytes bool sixZeros = false; if (sz % 4 != 0) { sz += (UInt16)2; sixZeros = true; } if (BodyEnd + sz > mData.Count) { AddBytes((int)(BodyEnd + sz) - mData.Count); } int stringLoc = (int)(BodyEnd - 4); //write hashId BinUtils.WriteNumberAtLocation(stringLoc, hashId, mData); // write the size BinUtils.Write2ByteNumberAtLocation(stringLoc + 4, sz, mData); // lay down string stringLoc += 6; /** MODIFYING 'stringLoc' NOW!! **/ for (int i = 0; i < content.Length; i++) { BinUtils.Write2ByteNumberAtLocation(stringLoc, content[i], mData); stringLoc += 2; } BinUtils.WriteNumberAtLocation(stringLoc, 0, mData); if (sixZeros) { BinUtils.Write2ByteNumberAtLocation(stringLoc + 4, 0, mData); } AddBodySize(sz); }
public List <byte> GetLocBytes() { /* special cases * if (current == '"') * { * sb.Append("\\\""); // escape the quote * cur.Append("\\\""); * } * else if (current == '\\') * { * sb.Append("\\\\"); // escape the escape! * cur.Append("\\\\"); * } */ string string_data = Content.Replace("\\\\", "\\").Replace("\\\"", "\"").Replace("\r\n", "\n").Replace("\n", "\r\n"); if (string_data == "") { string_data = " "; } uint hashId = LocHelper.GetHashId(StringId); UInt16 sz = (UInt16)((string_data.Length * 2) + 2 + 4 + 4); // 2:size info 4:hashId 4 min zero bytes if (sz % 4 != 0) { sz += (UInt16)2; } //if (string_data == "") sz = 0x10; // empty string hack bool sixZeros = false; // TODO: figure out how to tell if we use this. List <byte> mData = new List <byte>(new byte[sz]); //write hashId int stringLoc = 0; BinUtils.WriteNumberAtLocation(stringLoc, hashId, mData); // write the size BinUtils.Write2ByteNumberAtLocation(stringLoc + 4, sz, mData); // lay down string stringLoc += 6; /** MODIFYING 'stringLoc' NOW!! **/ for (int i = 0; i < string_data.Length; i++) { BinUtils.Write2ByteNumberAtLocation(stringLoc, string_data[i], mData); stringLoc += 2; } BinUtils.WriteNumberAtLocation(stringLoc, 0, mData); if (sixZeros) { BinUtils.Write2ByteNumberAtLocation(stringLoc + 4, 0, mData); } return(mData); }
/// <summary> /// String size seem to be always be a multiple of 4. With 4-6 'zero bytes' at the end /// </summary> /// <param name="stringId">the id of the string to modify</param> /// <param name="newValue">the new value</param> /// <returns>The string location, -1 if not found</returns> public int SetString(string stringId, string newValue) { uint hashId = GetHashId(stringId); StringBuilder sb = new StringBuilder(20); int stringLoc = GetString(hashId, sb); string prevValue = sb.ToString(); if (stringLoc > 0 && prevValue != newValue) { UInt32 oldSz = BinUtils.Get2ByteNumberAtLocation(stringLoc + 4, mData); UInt16 sz = (UInt16)((newValue.Length * 2) + 2 + 4 + 4); // 2:size info 4:hashId 4 min zero bytes if (sz % 4 != 0) { sz += (UInt16)2; } bool sixZeros = false; int diff = (int)(sz - oldSz); //2 * (newValue.Length - prevValue.Length); if (diff % 4 != 0) { diff = diff + 2; sixZeros = true; } int dataEnd = mData.Count + diff; if (diff > 0) { AddBytes(diff); ShiftDataDown(stringLoc, diff, dataEnd); } else if (diff < 0) { ShiftDataUp(stringLoc, -1 * diff, dataEnd); } //write hashId BinUtils.WriteNumberAtLocation(stringLoc, hashId, mData); // write the size BinUtils.Write2ByteNumberAtLocation(stringLoc + 4, sz, mData); // lay down string stringLoc += 6; /** MODIFYING 'stringLoc' NOW!! **/ for (int i = 0; i < newValue.Length; i++) { BinUtils.Write2ByteNumberAtLocation(stringLoc, newValue[i], mData); stringLoc += 2; } BinUtils.WriteNumberAtLocation(stringLoc, 0, mData); if (sixZeros) { BinUtils.Write2ByteNumberAtLocation(stringLoc + 4, 0, mData); } AddBodySize(diff); } return(stringLoc); }