From b36470e68060c879ad0acde296e808c810ed7454 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sat, 16 Nov 2024 10:16:37 -0500 Subject: [PATCH] feat: add CopyRef and Deref methods to RVType(Ptr) --- rmc_message.go | 6 ++---- types/any_data_holder.go | 15 ++++++++++++++- types/bool.go | 13 +++++++++++++ types/buffer.go | 13 +++++++++++++ types/class_version_container.go | 13 +++++++++++++ types/data.go | 13 +++++++++++++ types/datetime.go | 13 +++++++++++++ types/double.go | 13 +++++++++++++ types/float.go | 13 +++++++++++++ types/int16.go | 13 +++++++++++++ types/int32.go | 13 +++++++++++++ types/int64.go | 13 +++++++++++++ types/int8.go | 13 +++++++++++++ types/list.go | 13 +++++++++++++ types/map.go | 15 ++++++++++++++- types/pid.go | 13 +++++++++++++ types/qbuffer.go | 13 +++++++++++++ types/qresult.go | 13 +++++++++++++ types/quuid.go | 13 +++++++++++++ types/result_range.go | 13 +++++++++++++ types/rv_connection_data.go | 13 +++++++++++++ types/rv_type.go | 4 +++- types/station_url.go | 13 +++++++++++++ types/string.go | 13 +++++++++++++ types/uint16.go | 13 +++++++++++++ types/uint32.go | 13 +++++++++++++ types/uint64.go | 13 +++++++++++++ types/uint8.go | 13 +++++++++++++ types/variant.go | 26 ++++++++++++++++++-------- 29 files changed, 363 insertions(+), 15 deletions(-) diff --git a/rmc_message.go b/rmc_message.go index 4485dd7..a13d0f5 100644 --- a/rmc_message.go +++ b/rmc_message.go @@ -165,13 +165,11 @@ func (rmc *RMCMessage) decodeVerbose(data []byte) error { } versionContainer := types.NewClassVersionContainer() - ptr, _ := any(&versionContainer).(types.RVTypePtr) - - if err := ptr.ExtractFrom(stream); err != nil { + if err := versionContainer.ExtractFrom(stream); err != nil { return fmt.Errorf("Failed to read RMC Message ClassVersionContainer. %s", err.Error()) } - rmc.VersionContainer = ptr.(*types.ClassVersionContainer) + rmc.VersionContainer = &versionContainer rmc.Parameters = stream.ReadRemaining() } else { rmc.IsSuccess, err = stream.ReadBool() diff --git a/types/any_data_holder.go b/types/any_data_holder.go index f1ba8bc..f8a1b16 100644 --- a/types/any_data_holder.go +++ b/types/any_data_holder.go @@ -84,7 +84,7 @@ func (adh *AnyDataHolder) ExtractFrom(readable Readable) error { func (adh AnyDataHolder) Copy() RVType { copied := NewAnyDataHolder() - copied.TypeName = adh.TypeName.Copy().(String) + copied.TypeName = adh.TypeName copied.Length1 = adh.Length1.Copy().(UInt32) copied.Length2 = adh.Length2.Copy().(UInt32) copied.ObjectData = adh.ObjectData.Copy() @@ -115,6 +115,19 @@ func (adh AnyDataHolder) Equals(o RVType) bool { return adh.ObjectData.Equals(other.ObjectData) } +// CopyRef copies the current value of the AnyDataHolder +// and returns a pointer to the new copy +func (adh AnyDataHolder) CopyRef() RVTypePtr { + return &adh +} + +// Deref takes a pointer to the AnyDataHolder +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (adh *AnyDataHolder) Deref() RVType { + return *adh +} + // String returns a string representation of the struct func (adh AnyDataHolder) String() string { return adh.FormatToString(0) diff --git a/types/bool.go b/types/bool.go index b83c2aa..a1c54ee 100644 --- a/types/bool.go +++ b/types/bool.go @@ -36,6 +36,19 @@ func (b Bool) Equals(o RVType) bool { return b == other } +// CopyRef copies the current value of the Bool +// and returns a pointer to the new copy +func (b Bool) CopyRef() RVTypePtr { + return &b +} + +// Deref takes a pointer to the Bool +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (b *Bool) Deref() RVType { + return *b +} + // String returns a string representation of the Bool func (b Bool) String() string { return fmt.Sprintf("%t", b) diff --git a/types/buffer.go b/types/buffer.go index 29d07f9..226edc1 100644 --- a/types/buffer.go +++ b/types/buffer.go @@ -52,6 +52,19 @@ func (b Buffer) Equals(o RVType) bool { return bytes.Equal(b, o.(Buffer)) } +// CopyRef copies the current value of the Buffer +// and returns a pointer to the new copy +func (b Buffer) CopyRef() RVTypePtr { + return &b +} + +// Deref takes a pointer to the Buffer +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (b *Buffer) Deref() RVType { + return *b +} + // String returns a string representation of the struct func (b Buffer) String() string { return hex.EncodeToString(b) diff --git a/types/class_version_container.go b/types/class_version_container.go index ae0c1cb..ffe5e93 100644 --- a/types/class_version_container.go +++ b/types/class_version_container.go @@ -39,6 +39,19 @@ func (cvc ClassVersionContainer) Equals(o RVType) bool { return cvc.ClassVersions.Equals(o) } +// CopyRef copies the current value of the ClassVersionContainer +// and returns a pointer to the new copy +func (cvc ClassVersionContainer) CopyRef() RVTypePtr { + return &cvc +} + +// Deref takes a pointer to the ClassVersionContainer +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (cvc *ClassVersionContainer) Deref() RVType { + return *cvc +} + // String returns a string representation of the struct func (cvc ClassVersionContainer) String() string { return cvc.FormatToString(0) diff --git a/types/data.go b/types/data.go index 4bd725c..71eed2f 100644 --- a/types/data.go +++ b/types/data.go @@ -44,6 +44,19 @@ func (d Data) Equals(o RVType) bool { return d.StructureVersion == other.StructureVersion } +// CopyRef copies the current value of the Data +// and returns a pointer to the new copy +func (d Data) CopyRef() RVTypePtr { + return &d +} + +// Deref takes a pointer to the Data +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (d *Data) Deref() RVType { + return *d +} + // String returns a string representation of the struct func (d Data) String() string { return d.FormatToString(0) diff --git a/types/datetime.go b/types/datetime.go index f8bc9b8..10e1ef4 100644 --- a/types/datetime.go +++ b/types/datetime.go @@ -41,6 +41,19 @@ func (dt DateTime) Equals(o RVType) bool { return dt == o.(DateTime) } +// CopyRef copies the current value of the DateTime +// and returns a pointer to the new copy +func (dt DateTime) CopyRef() RVTypePtr { + return &dt +} + +// Deref takes a pointer to the DateTime +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (dt *DateTime) Deref() RVType { + return *dt +} + // Make initilizes a DateTime with the input data func (dt *DateTime) Make(year, month, day, hour, minute, second int) DateTime { *dt = DateTime(second | (minute << 6) | (hour << 12) | (day << 17) | (month << 22) | (year << 26)) diff --git a/types/double.go b/types/double.go index d6a5955..3d5135b 100644 --- a/types/double.go +++ b/types/double.go @@ -36,6 +36,19 @@ func (d Double) Equals(o RVType) bool { return d == other } +// CopyRef copies the current value of the Double +// and returns a pointer to the new copy +func (d Double) CopyRef() RVTypePtr { + return &d +} + +// Deref takes a pointer to the Double +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (d *Double) Deref() RVType { + return *d +} + // String returns a string representation of the Double func (d Double) String() string { return fmt.Sprintf("%f", d) diff --git a/types/float.go b/types/float.go index f474156..4705c13 100644 --- a/types/float.go +++ b/types/float.go @@ -36,6 +36,19 @@ func (f Float) Equals(o RVType) bool { return f == other } +// CopyRef copies the current value of the Float +// and returns a pointer to the new copy +func (f Float) CopyRef() RVTypePtr { + return &f +} + +// Deref takes a pointer to the Float +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (f *Float) Deref() RVType { + return *f +} + // String returns a string representation of the Float func (f Float) String() string { return fmt.Sprintf("%f", f) diff --git a/types/int16.go b/types/int16.go index aa6b746..f0b9b50 100644 --- a/types/int16.go +++ b/types/int16.go @@ -36,6 +36,19 @@ func (i16 Int16) Equals(o RVType) bool { return i16 == other } +// CopyRef copies the current value of the Int16 +// and returns a pointer to the new copy +func (i16 Int16) CopyRef() RVTypePtr { + return &i16 +} + +// Deref takes a pointer to the Int16 +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (i16 *Int16) Deref() RVType { + return *i16 +} + // String returns a string representation of the Int16 func (i16 Int16) String() string { return fmt.Sprintf("%d", i16) diff --git a/types/int32.go b/types/int32.go index e4ef52e..6bdd18e 100644 --- a/types/int32.go +++ b/types/int32.go @@ -36,6 +36,19 @@ func (i32 Int32) Equals(o RVType) bool { return i32 == other } +// CopyRef copies the current value of the Int32 +// and returns a pointer to the new copy +func (i32 Int32) CopyRef() RVTypePtr { + return &i32 +} + +// Deref takes a pointer to the Int32 +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (i32 *Int32) Deref() RVType { + return *i32 +} + // String returns a string representation of the Int32 func (i32 Int32) String() string { return fmt.Sprintf("%d", i32) diff --git a/types/int64.go b/types/int64.go index 01b1fb3..19eeea5 100644 --- a/types/int64.go +++ b/types/int64.go @@ -36,6 +36,19 @@ func (i64 Int64) Equals(o RVType) bool { return i64 == other } +// CopyRef copies the current value of the Int64 +// and returns a pointer to the new copy +func (i64 Int64) CopyRef() RVTypePtr { + return &i64 +} + +// Deref takes a pointer to the Int64 +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (i64 *Int64) Deref() RVType { + return *i64 +} + // String returns a string representation of the Int64 func (i64 Int64) String() string { return fmt.Sprintf("%d", i64) diff --git a/types/int8.go b/types/int8.go index 2ca1661..d47ff08 100644 --- a/types/int8.go +++ b/types/int8.go @@ -36,6 +36,19 @@ func (i8 Int8) Equals(o RVType) bool { return i8 == other } +// CopyRef copies the current value of the Int8 +// and returns a pointer to the new copy +func (i8 Int8) CopyRef() RVTypePtr { + return &i8 +} + +// Deref takes a pointer to the Int8 +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (i8 *Int8) Deref() RVType { + return *i8 +} + // String returns a string representation of the Int8 func (i8 Int8) String() string { return fmt.Sprintf("%d", i8) diff --git a/types/list.go b/types/list.go index 4e84ae0..128770c 100644 --- a/types/list.go +++ b/types/list.go @@ -87,6 +87,19 @@ func (l List[T]) Equals(o RVType) bool { return true } +// CopyRef copies the current value of the List +// and returns a pointer to the new copy +func (l List[T]) CopyRef() RVTypePtr { + return &l +} + +// Deref takes a pointer to the List +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (l *List[T]) Deref() RVType { + return *l +} + // Contains checks if the provided value exists in the List func (l List[T]) Contains(checkValue T) bool { for _, v := range l { diff --git a/types/map.go b/types/map.go index e2e7d64..ad23874 100644 --- a/types/map.go +++ b/types/map.go @@ -75,7 +75,7 @@ func (m *Map[K, V]) ExtractFrom(readable Readable) error { func (m Map[K, V]) copyType(t any) RVType { // * This just makes Map.Copy() a bit cleaner // * since it doesn't have to type check - if rvt, ok := t.(interface{ Copy() RVType }); ok { + if rvt, ok := t.(RVType); ok { return rvt.Copy() } @@ -127,6 +127,19 @@ func (m Map[K, V]) Equals(o RVType) bool { return true } +// CopyRef copies the current value of the Map +// and returns a pointer to the new copy +func (m Map[K, V]) CopyRef() RVTypePtr { + return &m +} + +// Deref takes a pointer to the Map +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (m *Map[K, V]) Deref() RVType { + return *m +} + // String returns a string representation of the struct func (m Map[K, V]) String() string { return m.FormatToString(0) diff --git a/types/pid.go b/types/pid.go index 839b828..6cc3e06 100644 --- a/types/pid.go +++ b/types/pid.go @@ -56,6 +56,19 @@ func (p PID) Equals(o RVType) bool { return p == o.(PID) } +// CopyRef copies the current value of the PID +// and returns a pointer to the new copy +func (p PID) CopyRef() RVTypePtr { + return &p +} + +// Deref takes a pointer to the PID +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (p *PID) Deref() RVType { + return *p +} + // String returns a string representation of the struct func (p PID) String() string { return p.FormatToString(0) diff --git a/types/qbuffer.go b/types/qbuffer.go index 272cda1..ee7c1ef 100644 --- a/types/qbuffer.go +++ b/types/qbuffer.go @@ -52,6 +52,19 @@ func (qb QBuffer) Equals(o RVType) bool { return bytes.Equal(qb, o.(QBuffer)) } +// CopyRef copies the current value of the QBuffer +// and returns a pointer to the new copy +func (qb QBuffer) CopyRef() RVTypePtr { + return &qb +} + +// Deref takes a pointer to the QBuffer +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (qb *QBuffer) Deref() RVType { + return *qb +} + // String returns a string representation of the struct func (qb QBuffer) String() string { return hex.EncodeToString(qb) diff --git a/types/qresult.go b/types/qresult.go index c97e549..65d9454 100644 --- a/types/qresult.go +++ b/types/qresult.go @@ -43,6 +43,19 @@ func (r QResult) Equals(o RVType) bool { return r == o.(QResult) } +// CopyRef copies the current value of the QResult +// and returns a pointer to the new copy +func (r QResult) CopyRef() RVTypePtr { + return &r +} + +// Deref takes a pointer to the QResult +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (r *QResult) Deref() RVType { + return *r +} + // IsSuccess returns true if the QResult is a success func (r QResult) IsSuccess() bool { return int(r)&errorMask == 0 diff --git a/types/quuid.go b/types/quuid.go index 6d12a81..88bab79 100644 --- a/types/quuid.go +++ b/types/quuid.go @@ -43,6 +43,19 @@ func (qu QUUID) Equals(o RVType) bool { return bytes.Equal(qu, o.(QUUID)) } +// CopyRef copies the current value of the QUUID +// and returns a pointer to the new copy +func (qu QUUID) CopyRef() RVTypePtr { + return &qu +} + +// Deref takes a pointer to the QUUID +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (qu *QUUID) Deref() RVType { + return *qu +} + // String returns a string representation of the struct func (qu QUUID) String() string { return qu.FormatToString(0) diff --git a/types/result_range.go b/types/result_range.go index 5fcb542..419e1ac 100644 --- a/types/result_range.go +++ b/types/result_range.go @@ -78,6 +78,19 @@ func (rr ResultRange) Equals(o RVType) bool { return rr.Length.Equals(&other.Length) } +// CopyRef copies the current value of the ResultRange +// and returns a pointer to the new copy +func (rr ResultRange) CopyRef() RVTypePtr { + return &rr +} + +// Deref takes a pointer to the ResultRange +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (rr *ResultRange) Deref() RVType { + return *rr +} + // String returns a string representation of the struct func (rr ResultRange) String() string { return rr.FormatToString(0) diff --git a/types/rv_connection_data.go b/types/rv_connection_data.go index 422de1a..796f08d 100644 --- a/types/rv_connection_data.go +++ b/types/rv_connection_data.go @@ -113,6 +113,19 @@ func (rvcd RVConnectionData) Equals(o RVType) bool { return true } +// CopyRef copies the current value of the RVConnectionData +// and returns a pointer to the new copy +func (rvcd RVConnectionData) CopyRef() RVTypePtr { + return &rvcd +} + +// Deref takes a pointer to the RVConnectionData +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (rvcd *RVConnectionData) Deref() RVType { + return *rvcd +} + // String returns a string representation of the struct func (rvcd RVConnectionData) String() string { return rvcd.FormatToString(0) diff --git a/types/rv_type.go b/types/rv_type.go index d36d87c..5aeb211 100644 --- a/types/rv_type.go +++ b/types/rv_type.go @@ -6,12 +6,14 @@ package types type RVType interface { WriteTo(writable Writable) Copy() RVType + CopyRef() RVTypePtr Equals(other RVType) bool } // RVTypePtr represents a pointer to an RVType. -// User to separate pointer receivers for easier type checking. +// Used to separate pointer receivers for easier type checking. type RVTypePtr interface { RVType ExtractFrom(readable Readable) error + Deref() RVType } diff --git a/types/station_url.go b/types/station_url.go index e56a689..a7ae7d9 100644 --- a/types/station_url.go +++ b/types/station_url.go @@ -141,6 +141,19 @@ func (s StationURL) Equals(o RVType) bool { return true } +// CopyRef copies the current value of the StationURL +// and returns a pointer to the new copy +func (s StationURL) CopyRef() RVTypePtr { + return &s +} + +// Deref takes a pointer to the StationURL +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (s *StationURL) Deref() RVType { + return *s +} + // Set sets a StationURL parameter. // // "custom" determines whether or not the parameter is a standard diff --git a/types/string.go b/types/string.go index 3fa6bb8..da62b7e 100644 --- a/types/string.go +++ b/types/string.go @@ -72,6 +72,19 @@ func (s String) Equals(o RVType) bool { return s == o.(String) } +// CopyRef copies the current value of the String +// and returns a pointer to the new copy +func (s String) CopyRef() RVTypePtr { + return &s +} + +// Deref takes a pointer to the String +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (s *String) Deref() RVType { + return *s +} + // String returns a string representation of the struct func (s String) String() string { return fmt.Sprintf("%q", string(s)) diff --git a/types/uint16.go b/types/uint16.go index a0be023..066d9f3 100644 --- a/types/uint16.go +++ b/types/uint16.go @@ -36,6 +36,19 @@ func (u16 UInt16) Equals(o RVType) bool { return u16 == other } +// CopyRef copies the current value of the UInt16 +// and returns a pointer to the new copy +func (u16 UInt16) CopyRef() RVTypePtr { + return &u16 +} + +// Deref takes a pointer to the UInt16 +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (u16 *UInt16) Deref() RVType { + return *u16 +} + // String returns a string representation of the UInt16 func (u16 UInt16) String() string { return fmt.Sprintf("%d", u16) diff --git a/types/uint32.go b/types/uint32.go index 9fade2a..b234199 100644 --- a/types/uint32.go +++ b/types/uint32.go @@ -36,6 +36,19 @@ func (u32 UInt32) Equals(o RVType) bool { return u32 == other } +// CopyRef copies the current value of the UInt32 +// and returns a pointer to the new copy +func (u32 UInt32) CopyRef() RVTypePtr { + return &u32 +} + +// Deref takes a pointer to the UInt32 +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (u32 *UInt32) Deref() RVType { + return *u32 +} + // String returns a string representation of the UInt32 func (u32 UInt32) String() string { return fmt.Sprintf("%d", u32) diff --git a/types/uint64.go b/types/uint64.go index ce914e7..87f77b7 100644 --- a/types/uint64.go +++ b/types/uint64.go @@ -36,6 +36,19 @@ func (u64 UInt64) Equals(o RVType) bool { return u64 == other } +// CopyRef copies the current value of the UInt64 +// and returns a pointer to the new copy +func (u64 UInt64) CopyRef() RVTypePtr { + return &u64 +} + +// Deref takes a pointer to the UInt64 +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (u64 *UInt64) Deref() RVType { + return *u64 +} + // String returns a string representation of the UInt64 func (u64 UInt64) String() string { return fmt.Sprintf("%d", u64) diff --git a/types/uint8.go b/types/uint8.go index 0b4bc65..955f925 100644 --- a/types/uint8.go +++ b/types/uint8.go @@ -36,6 +36,19 @@ func (u8 UInt8) Equals(o RVType) bool { return u8 == other } +// CopyRef copies the current value of the UInt8 +// and returns a pointer to the new copy +func (u8 UInt8) CopyRef() RVTypePtr { + return &u8 +} + +// Deref takes a pointer to the UInt8 +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (u8 *UInt8) Deref() RVType { + return *u8 +} + // String returns a string representation of the UInt8 func (u8 UInt8) String() string { return fmt.Sprintf("%d", u8) diff --git a/types/variant.go b/types/variant.go index 1e43270..829be92 100644 --- a/types/variant.go +++ b/types/variant.go @@ -1,7 +1,6 @@ package types import ( - "errors" "fmt" "strings" ) @@ -48,17 +47,15 @@ func (v *Variant) ExtractFrom(readable Readable) error { return fmt.Errorf("Invalid Variant type ID %d", typeID) } - v.Type = VariantTypes[typeID].Copy() - - ptr, ok := any(&v.Type).(RVTypePtr) - if !ok { - return errors.New("Variant type data is not a valid RVType. Missing ExtractFrom pointer receiver") - } - + // * Create a new copy and get a pointer to it. + // * Required so that we have access to ExtractFrom + ptr := VariantTypes[typeID].CopyRef() if err := ptr.ExtractFrom(readable); err != nil { return fmt.Errorf("Failed to read Variant type data. %s", err.Error()) } + v.Type = ptr.Deref() // * Dereference the RVTypePtr pointer back into a non-pointer type + return nil } @@ -94,6 +91,19 @@ func (v Variant) Equals(o RVType) bool { return true } +// CopyRef copies the current value of the Variant +// and returns a pointer to the new copy +func (v Variant) CopyRef() RVTypePtr { + return &v +} + +// Deref takes a pointer to the Variant +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (v *Variant) Deref() RVType { + return *v +} + // String returns a string representation of the struct func (v Variant) String() string { return v.FormatToString(0)