public void LocalSave() { string path = Application.persistentDataPath + "/Documents/"; if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.OSXEditor) { path = Application.dataPath + "/../Documents/"; } if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); bw.Write(mVersion); IRecordset rec = RecordFactory.CreateRecord(mVersion); if (rec != null) { rec.SaveData(bw); } byte[] buffer = ms.ToArray(); ms.Close(); bw.Close(); buffer = CryptBuffer(buffer); Stream stream = File.Open(path + "MiaoBoxLocal", FileMode.Create); stream.Write(buffer, 0, buffer.Length); stream.Flush(); stream.Close(); Debug.Log("save"); }
/// <summary> /// Sends all written data that has not been sent over the socket. If nothing has been written to the stream /// or everything has already been flushed, this method does not throw and does not send anything through the socket. /// If this stream is in read mode or has been closed or disposed, this method throws. /// </summary> public override void Flush() { if (IsDisposed) { throw new ObjectDisposedException("SocketStream"); } if (IsReadMode) { throw new InvalidOperationException("Can't flush a SocketStream that is in Read Mode"); } IEnumerator <RecordContentsStream> it = UnderlyingStreams.GetEnumerator(); try { // Move until the last flushed stream if (LastFlushedStream != null) { while (it.MoveNext()) { if (it.Current == LastFlushedStream) { break; } } } // Now flush the ones that haven't been flushed for real! while (it.MoveNext()) { // We have to make sure that the current stream is not empty, // because that would mean us sending an empty record here, when it should only happen in Close() if (it.Current.Length == 0) { continue; } using (var record = (StreamRecordBase)RecordFactory.CreateRecord(RequestId, RecordType)) { record.Contents = it.Current; Send(record); } } } catch { it.Dispose(); throw; } // Internal bookkeeping LastFlushedStream = LastUnfilledStream; var newLastStream = new RecordContentsStream(); underlyingStreams.AddLast(newLastStream); LastUnfilledStream = newLastStream; }
/** * Create an array of records from an input stream * * @param in the InputStream from which the records will be * obtained * * @exception RecordFormatException on error Processing the * InputStream */ public void ProcessRecords(Stream in1) { Record last_record = null; RecordInputStream recStream = new RecordInputStream(in1); while (recStream.HasNextRecord) { recStream.NextRecord(); Record[] recs = RecordFactory.CreateRecord(recStream); // handle MulRK records if (recs.Length > 1) { for (int k = 0; k < recs.Length; k++) { if (last_record != null) { if (!ProcessRecord(last_record)) { return; } } last_record = recs[k]; // do to keep the algorithm homogeneous...you can't } // actually continue a number record anyhow. } else { Record record = recs[0]; if (record != null) { if (last_record != null) { if (!ProcessRecord(last_record)) { return; } } last_record = record; } } } if (last_record != null) { ProcessRecord(last_record); } }
public void TestCreateRecord() { BOFRecord bof = new BOFRecord(); bof.Build = ((short)0); bof.BuildYear = ((short)1999); bof.RequiredVersion = (123); bof.Type = (BOFRecord.TYPE_WORKBOOK); bof.Version = ((short)0x06); bof.HistoryBitMask = (BOFRecord.HISTORY_MASK); byte[] bytes = bof.Serialize(); Record[] records = RecordFactory.CreateRecord(TestcaseRecordInputStream.Create(bytes)); Assert.IsTrue(records.Length == 1, "record.Length must be 1, was =" + records.Length); Assert.IsTrue(CompareRec(bof, records[0]), "record is the same"); }
public void TestSpecial() { short recType = RKRecord.sid; byte[] data = { 0, 0, 0, 0, 21, 0, 0, 0, 0, 0 }; Record[] record = RecordFactory.CreateRecord(TestcaseRecordInputStream.Create(recType, data)); Assert.AreEqual(typeof(NumberRecord).Name, record[0].GetType().Name); NumberRecord numberRecord = (NumberRecord)record[0]; Assert.AreEqual(0, numberRecord.Column); Assert.AreEqual(18, numberRecord.RecordSize); Assert.AreEqual(0, numberRecord.Row); Assert.AreEqual(515, numberRecord.Sid); Assert.AreEqual(0.0, numberRecord.Value, 0.001); Assert.AreEqual(21, numberRecord.XFIndex); }
public void TestBasicRecordConstruction() { short recType = BOFRecord.sid; byte[] data = { 0, 6, 5, 0, unchecked ((byte)-2), 28, unchecked ((byte)-51), 7, unchecked ((byte)-55), 64, 0, 0, 6, 1, 0, 0 }; Record[] record = RecordFactory.CreateRecord(TestcaseRecordInputStream.Create(recType, data)); Assert.AreEqual(typeof(BOFRecord).Name, record[0].GetType().Name); BOFRecord bofRecord = (BOFRecord)record[0]; Assert.AreEqual(7422, bofRecord.Build); Assert.AreEqual(1997, bofRecord.BuildYear); Assert.AreEqual(16585, bofRecord.HistoryBitMask); Assert.AreEqual(20, bofRecord.RecordSize); Assert.AreEqual(262, bofRecord.RequiredVersion); Assert.AreEqual(2057, bofRecord.Sid); Assert.AreEqual(5, bofRecord.Type); Assert.AreEqual(1536, bofRecord.Version); recType = MMSRecord.sid; //size = 2; data = new byte[] { 0, 0 }; record = RecordFactory.CreateRecord(TestcaseRecordInputStream.Create(recType, data)); Assert.AreEqual(typeof(MMSRecord).Name, record[0].GetType().Name); MMSRecord mmsRecord = (MMSRecord)record[0]; Assert.AreEqual(0, mmsRecord.GetAddMenuCount()); Assert.AreEqual(0, mmsRecord.GetDelMenuCount()); Assert.AreEqual(6, mmsRecord.RecordSize); Assert.AreEqual(193, mmsRecord.Sid); }
/// <summary> /// Flushes this stream (<see cref="Flush()"/>) and disposes it. If no data has been flushed, this method does nothing else. If some data was flushed, /// then this method flushes the remaining data and also sends an empty record through the socket, meaning end of stream to the other communicating party. /// If the stream is in read mode, this method does nothing. /// If this stream has already been disposed, this method does nothing, but does not throw either. /// This method never closes the underlying socket. /// </summary> public override void Close() { if (IsDisposed) { return; } // If this stream is empty, don't bother wasting network resources with an empty record // Or if this is in Read Mode, then we just don't send anything at all! if (Length == 0 || IsReadMode) { IsDisposed = true; return; } // Flush and send an empty record! this.Flush(); using (var emptyRecord = (StreamRecordBase)RecordFactory.CreateRecord(RequestId, RecordType)) { Send(emptyRecord); } IsDisposed = true; }
/// <summary> /// Returns the next available record, or null if /// this pass didn't return a record that's /// suitable for returning (eg was a continue record). /// </summary> /// <returns></returns> private Record GetNextRecord() { Record toReturn = null; if (in1.HasNextRecord) { // Grab our next record in1.NextRecord(); short sid = in1.Sid; // // for some reasons we have to make the workbook to be at least 4096 bytes // but if we have such workbook we Fill the end of it with zeros (many zeros) // // it Is not good: // if the Length( all zero records ) % 4 = 1 // e.g.: any zero record would be Readed as 4 bytes at once ( 2 - id and 2 - size ). // And the last 1 byte will be Readed WRONG ( the id must be 2 bytes ) // // So we should better to Check if the sid Is zero and not to Read more data // The zero sid shows us that rest of the stream data Is a fake to make workbook // certain size // if (sid == 0) { return(null); } // If we had a last record, and this one // Isn't a continue record, then pass // it on to the listener if ((rec != null) && (sid != ContinueRecord.sid)) { // This last record ought to be returned toReturn = rec; } // If this record Isn't a continue record, // then build it up if (sid != ContinueRecord.sid) { //Console.WriteLine("creating "+sid); Record[] recs = RecordFactory.CreateRecord(in1); // We know that the multiple record situations // don't contain continue records, so just // pass those on to the listener now if (recs.Length > 1) { bonusRecords = new ArrayList(recs.Length - 1); for (int k = 0; k < (recs.Length - 1); k++) { bonusRecords.Add(recs[k]); } } // Regardless of the number we Created, always hold // onto the last record to be Processed on the next // loop, in case it has any continue records rec = recs[recs.Length - 1]; // Don't return it just yet though, as we probably have // a record from the last round to return } else { // Normally, ContinueRecords are handled internally // However, in a few cases, there Is a gap between a record at // its Continue, so we have to handle them specially // This logic Is much like in RecordFactory.CreateRecords() Record[] recs = RecordFactory.CreateRecord(in1); ContinueRecord crec = (ContinueRecord)recs[0]; if ((lastRec is ObjRecord) || (lastRec is TextObjectRecord)) { // You can have Obj records between a DrawingRecord // and its continue! lastDrawingRecord.ProcessContinueRecord(crec.Data); // Trigger them on the drawing record, now it's complete rec = lastDrawingRecord; } else if ((lastRec is DrawingGroupRecord)) { ((DrawingGroupRecord)lastRec).ProcessContinueRecord(crec.Data); // Trigger them on the drawing record, now it's complete rec = lastRec; } else { if (rec is UnknownRecord) { ;//silently skip records we don't know about } else { throw new RecordFormatException("Records should handle ContinueRecord internally. Should not see this exception"); } } } // Update our tracking of the last record lastRec = rec; if (rec is DrawingRecord) { lastDrawingRecord = (DrawingRecord)rec; } } else { // No more records hitEOS = true; } // If we've hit the end-of-stream, then // finish off the last record and be done if (hitEOS) { complete = true; // Return the last record if there was // one, otherwise null if (rec != null) { toReturn = rec; rec = null; } } return(toReturn); }
public UninstallLog(Stream stream) { byte[] buffer = new byte[128]; // TUninstallLogID = array[0..63] of AnsiChar; string id = stream.ReadString(buffer, 64); if (id == IDx64) { isX64 = true; } else if (id == IDx86) { isX64 = false; } else { throw new Exception("Header ID corrupted"); } // array[0..127] of AnsiChar; appId = stream.ReadString(buffer, 128); // array[0..127] of AnsiChar; appName = stream.ReadString(buffer, 128); version = stream.ReadInt(buffer); int numRecords = stream.ReadInt(buffer); // endOffset - ignored stream.Read(buffer, 0, 4); flags = (UninstallLogFlags)stream.ReadInt(buffer); // array[0..26] of Longint; { reserved for future use } stream.Seek(27 * 4, SeekOrigin.Current); // skip header CRC, as we whiil not check it anyway stream.Read(buffer, 0, 4); using (CrcStream crcStream = new CrcStream(stream)) { for (int i = 0; i < numRecords; i++) { /* * TUninstallFileRec = packed record (packed, so no alignment) * Typ: TUninstallRecTyp; (ushort) * ExtraData: Longint; (int) * DataSize: Cardinal; (uint) * end; */ // ReadBuf(FileRec, SizeOf(FileRec)); RecordType type = (RecordType)crcStream.ReadUShort(buffer); int extraData = crcStream.ReadInt(buffer); uint dataSize = crcStream.ReadUInt(buffer); System.Diagnostics.Debug.WriteLine($"Read type: {type}; Extra: {extraData}; Data Size: {dataSize}"); // ReadBuf(NewRec.Data, NewRec.DataSize); byte[] data = new byte[dataSize]; crcStream.Read(data, 0, (int)dataSize); records.Add(RecordFactory.CreateRecord(type, extraData, data)); } } }
public byte LocalLoad() { string path = Application.persistentDataPath + "/Documents/"; if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.OSXEditor) { path = Application.dataPath + "/../Documents/"; } if (File.Exists(path + "MiaoBoxLocal")) { Stream stream = File.Open(path + "MiaoBoxLocal", FileMode.Open); byte[] original = GetBytesFromStream(stream); byte[] buffer = DecryptBuffer(original); stream.Close(); MemoryStream ms = new MemoryStream(buffer); BinaryReader br = new BinaryReader(ms); string ver = string.Empty; try { Debug.Log("Load"); //BinaryReader.ReadString()方法如何确定从数据流中读多少内容 //是这样的,BinaryReader.ReadString是和BinaryWriter.Write(string)配合使用的。 //使用后者写入文件的时候,如果写入字符串,是会将字符串的长度也写在文件中的。你可以用BinaryWriter.Write(string)写入文件 ver = br.ReadString(); mReadVersion = ver; IRecordset rec = RecordFactory.CreateRecord(mReadVersion); if (rec != null) { rec.LoadData(br); } } catch (System.Exception e) { Debug.LogWarning("Version: " + ver); Debug.LogWarning(e.StackTrace); if (!File.Exists(path + "MiaoBoxLocal" + "_" + ver)) { File.Copy(path + "MiaoBoxLocal", path + "MiaoBoxLocal" + "_" + ver); } return(1); } finally { br.Close(); ms.Close(); } if (!ver.Equals(mVersion)) { LocalSave(); } return(0); } else { return(2); } }