Swiftgram/Postbox/Message.swift
2016-01-26 16:16:40 +03:00

215 lines
6.0 KiB
Swift

import Foundation
public struct MessageId: Hashable, Comparable, CustomStringConvertible {
public typealias Namespace = Int32
public typealias Id = Int32
public let peerId: PeerId
public let namespace: Namespace
public let id: Id
public var hashValue: Int {
get {
return Int(self.id)
}
}
public var description: String {
get {
return "\(namespace):\(id)"
}
}
public init(peerId: PeerId, namespace: Namespace, id: Id) {
self.peerId = peerId
self.namespace = namespace
self.id = id
}
public init(_ buffer: ReadBuffer) {
var peerIdNamespaceValue: Int32 = 0
memcpy(&peerIdNamespaceValue, buffer.memory + buffer.offset, 4)
var peerIdIdValue: Int32 = 0
memcpy(&peerIdIdValue, buffer.memory + (buffer.offset + 4), 4)
self.peerId = PeerId(namespace: peerIdNamespaceValue, id: peerIdIdValue)
var namespaceValue: Int32 = 0
memcpy(&namespaceValue, buffer.memory + (buffer.offset + 8), 4)
self.namespace = namespaceValue
var idValue: Int32 = 0
memcpy(&idValue, buffer.memory + (buffer.offset + 12), 4)
self.id = idValue
buffer.offset += 16
}
public func encodeToBuffer(buffer: WriteBuffer) {
var peerIdNamespace = self.peerId.namespace
var peerIdId = self.peerId.id
var namespace = self.namespace
var id = self.id
buffer.write(&peerIdNamespace, offset: 0, length: 4);
buffer.write(&peerIdId, offset: 0, length: 4);
buffer.write(&namespace, offset: 0, length: 4);
buffer.write(&id, offset: 0, length: 4);
}
public static func encodeArrayToBuffer(array: [MessageId], buffer: WriteBuffer) {
var length: Int32 = Int32(array.count)
buffer.write(&length, offset: 0, length: 4)
for id in array {
id.encodeToBuffer(buffer)
}
}
public static func decodeArrayFromBuffer(buffer: ReadBuffer) -> [MessageId] {
var length: Int32 = 0
memcpy(&length, buffer.memory, 4)
buffer.offset += 4
var i = 0
var array: [MessageId] = []
while i < Int(length) {
array[i] = MessageId(buffer)
i++
}
return array
}
}
public func ==(lhs: MessageId, rhs: MessageId) -> Bool {
return lhs.id == rhs.id && lhs.namespace == rhs.namespace
}
public func <(lhs: MessageId, rhs: MessageId) -> Bool {
if lhs.namespace == rhs.namespace {
return lhs.id < rhs.id
} else {
return lhs.namespace < rhs.namespace
}
}
public struct MessageIndex: Equatable, Comparable {
public let id: MessageId
public let timestamp: Int32
public init(_ message: Message) {
self.id = message.id
self.timestamp = message.timestamp
}
init(_ message: StoreMessage) {
self.id = message.id
self.timestamp = message.timestamp
}
public init(id: MessageId, timestamp: Int32) {
self.id = id
self.timestamp = timestamp
}
public func predecessor() -> MessageIndex {
return MessageIndex(id: MessageId(peerId: self.id.peerId, namespace: self.id.namespace, id: self.id.id - 1), timestamp: self.timestamp)
}
public func successor() -> MessageIndex {
return MessageIndex(id: MessageId(peerId: self.id.peerId, namespace: self.id.namespace, id: self.id.id + 1), timestamp: self.timestamp)
}
}
public func ==(lhs: MessageIndex, rhs: MessageIndex) -> Bool {
return lhs.id == rhs.id && lhs.timestamp == rhs.timestamp
}
public func <(lhs: MessageIndex, rhs: MessageIndex) -> Bool {
if lhs.timestamp != rhs.timestamp {
return lhs.timestamp < rhs.timestamp
}
if lhs.id.namespace != rhs.id.namespace {
return lhs.id.namespace < rhs.id.namespace
}
return lhs.id.id < rhs.id.id
}
public class Message {
let id: MessageId
let timestamp: Int32
let text: String
let attributes: [Coding]
let media: [Media]
init(id: MessageId, timestamp: Int32, text: String, attributes: [Coding], media: [Media]) {
self.id = id
self.timestamp = timestamp
self.text = text
self.attributes = attributes
self.media = media
}
}
class StoreMessage {
let id: MessageId
let timestamp: Int32
let text: String
let attributes: [Coding]
let media: [Media]
init(id: MessageId, timestamp: Int32, text: String, attributes: [Coding], media: [Media]) {
self.id = id
self.timestamp = timestamp
self.text = text
self.attributes = attributes
self.media = media
}
}
class IntermediateMessage {
let id: MessageId
let timestamp: Int32
let text: String
let attributesData: ReadBuffer
let embeddedMediaData: ReadBuffer
let referencedMedia: [MediaId]
init(id: MessageId, timestamp: Int32, text: String, attributesData: ReadBuffer, embeddedMediaData: ReadBuffer, referencedMedia: [MediaId]) {
self.id = id
self.timestamp = timestamp
self.text = text
self.attributesData = attributesData
self.embeddedMediaData = embeddedMediaData
self.referencedMedia = referencedMedia
}
}
public struct RenderedMessage: Equatable, Comparable {
public let message: Message
internal let incomplete: Bool
public let peers: [Peer]
public let media: [Media]
internal init(message: Message) {
self.message = message
self.peers = []
self.media = []
self.incomplete = true
}
internal init(message: Message, peers: [Peer], media: [Media]) {
self.message = message
self.peers = peers
self.media = media
self.incomplete = false
}
}
public func ==(lhs: RenderedMessage, rhs: RenderedMessage) -> Bool {
return lhs.message.id == rhs.message.id
}
public func <(lhs: RenderedMessage, rhs: RenderedMessage) -> Bool {
return MessageIndex(lhs.message) < MessageIndex(rhs.message)
}