Code archives/Miscellaneous/Object streams
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
Class "TData" - for define a user save\load algorithm ( method ToString() = "class name" ) The 2 ways for creating objects streams: 1) stream = CreateObjectStream(stream) 2) stream = ReadStream("object::file.txt") no save tag : "no_save" | "no_save=1" current version : 1.21 | |||||
Rem (с) 2012 Альберт Гаскаров. Все права защищены. Лицензионное соглашение дает Вам право распространять файлы с любыми Вашими приложениями, которые в свою очередь обязаны распространяться со следующей суб-лицензией: "Все файлы включенный в данное приложение является интеллектуальной собственностью автора и не может распространятся отдельно от данного приложения без личного разрешения автора." Также ЗАПРЕЩЕНО распространять все остальные файлы, включенные в данный архив (дистрибутив) без личного разрешения автора. ВНИМАНИЕ! ПОЖАЛУЙСТА ПРОЧТИТЕ ВНИМАТЕЛЬНО:КОПИРУЯ ИЛИ ИСПОЛЬЗУЯ ЛЮБЫМ ИНЫМ ОБРАЗОМ ПРОГРАММНЫЙ ПРОДУКТ, ПОСТАВЛЯЕМЫЙ С ДАННЫМ ЛИЦЕНЗИОННЫМ СОГЛАШЕНИЕМ, ВЫ (КАК ЮРИДИЧЕСКОЕ ИЛИ ФИЗИЧЕСКОЕ ЛИЦО), СОГЛАШАЕТЕСЬ СО ВСЕМИ УСЛОВИЯМИ НАСТОЯЩЕГО ЛИЦЕНЗИОННОГО СОГЛАШЕНИЯ (ДАЛЕЕ ПО ТЕКСТУ "СОГЛАШЕНИЕ"), ПРИВЕДЕННЫМИ НИЖЕ, ОТНОСИТЕЛЬНО ИСПОЛЬЗОВАНИЯ ПРОГРАММНОГО ПРОДУКТА (ДАЛЕЕ ПО ТЕКСТУ "ПО"). ЕСЛИ ВЫ НЕ СОГЛАСНЫ ПРИНЯТЬ НА СЕБЯ УСЛОВИЯ СОГЛАШЕНИЯ, ВЫ НЕ ИМЕЕТЕ ПРАВА ИСПОЛЬЗОВАТЬ ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ В КАКИХ ЛИБО ЦЕЛЯХ И ОБЯЗАНЫ УДАЛИТЬ ВСЕ КОПИИ ПРОГРАММНОГО ПРОДУКТА С КОМПЬЮТЕРОВ И НОСИТЕЛЕЙ, ПРИНАДЛЕЖАЩИХ ВАМ. EndRem SuperStrict Rem bbdoc: Данные End Rem Module data.TData ModuleInfo "Версия: 1.21" ModuleInfo "Автор : Альберт Гаскаров" ModuleInfo "Сервер: API" ModuleInfo "История: 1.21" ModuleInfo "История: Доработки" ModuleInfo "История: 1.20" ModuleInfo "История: Переработка модуля" ModuleInfo "История: 1.16" ModuleInfo "История: Добавлены методы Write\ReadCString в качестве эксперимента" ModuleInfo "История: 1.15" ModuleInfo "История: Добавлен флаг 'no_save' классам" ModuleInfo "История: 1.14" ModuleInfo "История: Переименован метод Tag() -> ToString()" ModuleInfo "История: Теперь в методе ToString() можно задавать фильтр" ModuleInfo "История: 1.12" ModuleInfo "История: Доработки в деструкторе" ModuleInfo "История: Создание обьектного потока теперь происходит через метод-конструктор" ModuleInfo "История: 1.10" ModuleInfo "История: Улучшения" ModuleInfo "История: Улучшения" ModuleInfo "История: 1.00" ModuleInfo "История: Первый релиз" Import brl.blitz ' import BlitzMax Import brl.stream ' import TStream class Import brl.reflection ' import Objects reflection Public Rem bbdoc: Обьект данных End Rem Type TData Abstract Method New() TObjectStream._datas:+[Self] End Method Rem bbdoc: Тэг" End Rem Method ToString:String() Abstract Rem bbdoc: Функция чтения обьекта End Rem Method ReadObject:Object(stream:TStream) Abstract Rem bbdoc: Функция записи обьекта End Rem Method WriteObject(obj:Object, stream:TStream) Abstract End Type Rem bbdoc: Обьект данных End Rem Function CreateObjectStream:TStream(stream:TStream) Return New TObjectStream.Create(stream) End Function Private rem ------OBJECT-STREAMS------ | PROTOCOL : "object" | | NOSAVE TAG : "no_save" | -------------------------- -------------------------READING-------------------------- | Local stream:TStream = ReadStream("object::file.txt") | | Local obj:Object = stream.ReadObject() | ---------------------------------------------------------- -------------------------WRITEING------------------------- | Local stream:TStream = WriteStream("object::file.txt") | | stream.WriteObject(obj) | ---------------------------------------------------------- endrem Type TObjectStream Extends TStreamWrapper Global _datas:TData[] Global _tid:TTypeId = Null Method Close() _stream.Close() SetStream(Null) End Method Method Delete() If _stream Then Close() End Method Method Create:TStream(stream:TStream) SetStream(stream) Return Self End Method Method ClearArrayName:String(name:String) Return name[..name.FindLast("[")] End Method Method DataTypeId:TData(tid:TTypeId) Local tags:String[], i:Int For Local data:TData = EachIn _datas tags = data.ToString().Split(" ") If tid.Name().ToLower() <> tags[0].ToLower() Then Continue For i = 1 Until tags.Length If Not tid.MetaData(tags[i]) i = 0 Exit End If Next If i = 0 Then Continue Return data Next End Method rem Method WriteCString:Int(str:String) Return Write(str + "~0", str.Length + 1) End Method Method ReadCString:String() Local mem:Byte Ptr = MemAlloc(Size() - pos()) Local i:Int While Not Eof() mem[i] = ReadByte() If mem[i] = 0 Then Exit i:+1 Wend Local str:String = String.FromCString(mem) MemFree(mem) Return str End Method end rem '-------------------------------------------------------------------------------------------------------------- Method ReadObject:Object() Select ReadByte() Case 59 Return Null Case 123 Default Throw New TStreamReadException End Select Local tid:TTypeId = ReadTypeId() Local obj:Object = ReadSingle(tid) If obj Then Return obj If tid.MetaData("no_save") Then Return tid.NewObject() obj = ReadArray(tid) If obj Then Return obj obj = ReadFromData(tid) If obj Then Return obj Return ReadFields(tid) End Method Method ReadTypeId:TTypeId() Local mem:Byte Ptr = MemAlloc(Size() - pos()) Local i:Int While Not Eof() mem[i] = ReadByte() If mem[i] = 125 mem[i] = 0 Exit End If i:+1 Wend Local name:String = String.FromCString(mem) MemFree(mem) ?Debug Local t:TTypeId = TTypeId.ForName(name) If Not t Then WriteStdout("WARNING! Type id not created -> " + name + "~n") Return t ? Return TTypeId.ForName(name) End Method Method ReadSingle:Object(tid:TTypeId) Select tid Case ByteTypeId Return String.FromInt(ReadByte()) Case ShortTypeId Return String.FromInt(ReadShort()) Case IntTypeId Return String.FromInt(ReadInt()) Case LongTypeId Return String.FromLong(ReadLong()) Case FloatTypeId Return String.FromFloat(ReadFloat()) Case DoubleTypeId Return String.FromDouble(ReadDouble()) Case StringTypeId Return ReadString(ReadInt()) End Select End Method Method ReadArray:Object(tid:TTypeId) If tid.ElementType() Local dims:Int = ReadInt() Local array:Int[] = New Int[dims] Local ln:Int For Local i:Int = 0 Until dims array[i] = ReadInt() If i = 0 ln = array[i] Else array[i + ~0] :/array[i] End If Next Local obj:Object = tid.NewArray(ln, array) Local etid:TTypeId = TTypeId.ForName(ClearArrayName(tid.Name())) For Local pos:Int = 0 Until ln Select etid Case ByteTypeId tid.SetArrayElement(obj, pos, Object(String(ReadByte()))) Case ShortTypeId tid.SetArrayElement(obj, pos, Object(String(ReadShort()))) Case IntTypeId tid.SetArrayElement(obj, pos, Object(String(ReadInt()))) Case LongTypeId tid.SetArrayElement(obj, pos, Object(String(ReadLong()))) Case FloatTypeId tid.SetArrayElement(obj, pos, Object(String(ReadFloat()))) Case DoubleTypeId tid.SetArrayElement(obj, pos, Object(String(ReadDouble()))) Case StringTypeId tid.SetArrayElement(obj, pos, Object(ReadString(ReadInt()))) Default tid.SetArrayElement(obj, pos, ReadObject()) End Select Next Return obj End If End Method Method ReadFromData:Object(tid:TTypeId) Local data:TData = DataTypeId(tid) If data Then Return data.ReadObject(Self) End Method Method ReadFields:Object(tid:TTypeId) Local obj:Object = tid.NewObject() For Local f:TField = EachIn tid.EnumFields() If f.MetaData("no_save") Then Continue Local etid:TTypeId = TTypeId.ForName(f.TypeId().Name()) DebugLog "Reading field : " + etid.Name() Select etid Case ByteTypeId f.SetInt(obj, ReadByte()) Case ShortTypeId f.SetInt(obj, ReadShort()) Case IntTypeId f.SetInt(obj, ReadInt()) Case LongTypeId f.SetLong(obj, ReadLong()) Case FloatTypeId f.SetFloat(obj, ReadFloat()) Case DoubleTypeId f.SetDouble(obj, ReadDouble()) Case StringTypeId f.SetString(obj, ReadString(ReadInt())) Default f.Set(obj, ReadObject()) End Select Next Return obj End Method '-------------------------------------------------------------------------------------------------------------- Method WriteObject:Int(obj:Object) If Not obj WriteByte(59) Return False End If WriteByte(123) Local tid:TTypeId = _tid _tid = Null If tid = ObjectTypeId Then tid = TTypeId.ForObject(obj) If Not tid Then tid = TTypeId.ForObject(obj) DebugLog "TID = " + tid.Name() If Not WriteTypeId(tid) Then Return False If WriteSingle(tid, obj) Then Return True If tid.MetaData("no_save") Then Return True If WriteArray(tid, obj) Then Return True If WriteData(tid, obj) Then Return True Return WriteFields(tid, obj) End Method Method WriteTypeId:Byte(tid:TTypeId) DebugLog "Writing : " + tid.Name() Local name:String = tid.Name() + "}" Return WriteBytes(name, name.Length) = name.Length End Method Method WriteSingle:Byte(tid:TTypeId, obj:Object) Select tid Case ByteTypeId WriteByte(Byte(obj.ToString())) ; Return True Case ShortTypeId WriteShort(Short(obj.ToString())) ; Return True Case IntTypeId WriteInt(Int(obj.ToString())) ; Return True Case LongTypeId WriteLong(Long(obj.ToString())) ; Return True Case FloatTypeId WriteFloat(Float(obj.ToString())) ; Return True Case DoubleTypeId WriteDouble(Double(obj.ToString())) ; Return True Case StringTypeId WriteInt(obj.ToString().Length) WriteString(obj.ToString()) Return True End Select End Method Method WriteArray:Byte(tid:TTypeId, obj:Object) If tid.Name().EndsWith("]") Local etid:TTypeId = TTypeId.ForName(ClearArrayName(tid.Name())) WriteInt(tid.ArrayDimensions(obj)) For Local i:Int = 0 Until tid.ArrayDimensions(obj) WriteInt(tid.ArrayLength(obj, i)) Next For Local pos:Int = 0 Until tid.ArrayLength(obj) Select etid Case ByteTypeId WriteByte(tid.GetArrayElement(obj, pos).ToString().ToInt()) Case ShortTypeId WriteShort(tid.GetArrayElement(obj, pos).ToString().ToInt()) Case IntTypeId WriteInt(tid.GetArrayElement(obj, pos).ToString().ToInt()) Case LongTypeId WriteLong(tid.GetArrayElement(obj, pos).ToString().ToLong()) Case FloatTypeId WriteFloat(tid.GetArrayElement(obj, pos).ToString().ToFloat()) Case DoubleTypeId WriteDouble(tid.GetArrayElement(obj, pos).ToString().ToDouble()) Case StringTypeId WriteInt(tid.GetArrayElement(obj, pos).ToString().Length) WriteString(tid.GetArrayElement(obj, pos).ToString()) Default _tid = Null WriteObject(tid.GetArrayElement(obj, pos)) End Select Next Return True End If End Method Method WriteData:Byte(tid:TTypeId, obj:Object) Local data:TData = DataTypeId(tid) If data data.WriteObject(obj, Self) Return True End If End Method Method WriteFields:Byte(tid:TTypeId, obj:Object) For Local f:TField = EachIn tid.EnumFields() If f.MetaData("no_save") Then Continue Local etid:TTypeId = f.TypeId() DebugLog "Write field : " + etid.Name() Select etid Case ByteTypeId WriteByte(f.GetInt(obj)) Case ShortTypeId WriteShort(f.GetInt(obj)) Case IntTypeId WriteInt(f.GetInt(obj)) Case LongTypeId WriteLong(f.GetLong(obj)) Case FloatTypeId WriteFloat(f.GetFloat(obj)) Case DoubleTypeId WriteDouble(f.GetDouble(obj)) Case StringTypeId WriteInt(f.GetString(obj).Length) WriteString(f.GetString(obj)) Default _tid = etid WriteObject(f.Get(obj)) End Select Next Return True End Method End Type Type TObjectStreamFactory Extends TStreamFactory Method CreateStream:TStream(url:Object, proto:String, path:String, readable:Int, writeable:Int) If proto = "object" Then Local stream:TStream = OpenStream(path, readable, writeable) If stream Then Return New TObjectStream.Create(stream) End If End Method End Type Function Free() TObjectStream._datas = Null TObjectStream._tid = Null End Function Function install() New TObjectStreamFactory OnEnd(Free) End Function install() |
Comments
None.
Code Archives Forum