Remove some more RP related code

// FREEBIE
This commit is contained in:
Michael Kirk 2017-03-27 12:26:13 -04:00
parent 3765d28da9
commit 0b49037179
78 changed files with 65 additions and 3500 deletions

View File

@ -58,7 +58,6 @@
452ECA4D1E087E7200E2F016 /* MessageFetcherJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 452ECA4C1E087E7200E2F016 /* MessageFetcherJob.swift */; };
452ECA4E1E087E7200E2F016 /* MessageFetcherJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 452ECA4C1E087E7200E2F016 /* MessageFetcherJob.swift */; };
4531C9C41DD8E6D800F08304 /* JSQMessagesCollectionViewCell+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 4531C9C31DD8E6D800F08304 /* JSQMessagesCollectionViewCell+OWS.m */; };
453201251E71100C00F20761 /* DisplayableTextFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453201241E71100C00F20761 /* DisplayableTextFilter.swift */; };
45387B041E36D650005D00B3 /* OWS102MoveLoggingPreferenceToUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 45387B031E36D650005D00B3 /* OWS102MoveLoggingPreferenceToUserDefaults.m */; };
453D28B71D32BA5F00D523F0 /* OWSDisplayedMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 453D28B61D32BA5F00D523F0 /* OWSDisplayedMessage.m */; };
453D28BA1D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = 453D28B91D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.m */; };
@ -135,8 +134,9 @@
45E1F3A31DEF1DF000852CF1 /* NoSignalContactsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 45E1F3A21DEF1DF000852CF1 /* NoSignalContactsView.xib */; };
45E1F3A51DEF20A100852CF1 /* NoSignalContactsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45E1F3A41DEF20A100852CF1 /* NoSignalContactsView.swift */; };
45E2E9201E153B3D00457AA0 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45E2E91F1E153B3D00457AA0 /* Strings.swift */; };
45E615161E8C590B0018AD52 /* DisplayableTextFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45E615151E8C590B0018AD52 /* DisplayableTextFilter.swift */; };
45E615171E8C59100018AD52 /* DisplayableTextFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45E615151E8C590B0018AD52 /* DisplayableTextFilter.swift */; };
45E7A6A81E71CA7E00D44FB5 /* DisplayableTextFilterTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45E7A6A61E71CA7E00D44FB5 /* DisplayableTextFilterTest.swift */; };
45E7A6A91E71CC2E00D44FB5 /* DisplayableTextFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453201241E71100C00F20761 /* DisplayableTextFilter.swift */; };
45EB32CF1D7465C900735B2E /* OWSLinkedDevicesTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 45EB32CE1D7465C900735B2E /* OWSLinkedDevicesTableViewController.m */; };
45F170AC1E2F0351003FC1F2 /* CallAudioSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45F170AB1E2F0351003FC1F2 /* CallAudioSession.swift */; };
45F170AD1E2F0351003FC1F2 /* CallAudioSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45F170AB1E2F0351003FC1F2 /* CallAudioSession.swift */; };
@ -159,10 +159,8 @@
45FBC5D21DF8592E00E9B410 /* SignalCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45FBC5D01DF8592E00E9B410 /* SignalCall.swift */; };
4CE0E3771B954546007210CF /* TSAnimatedAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE0E3761B954546007210CF /* TSAnimatedAdapter.m */; };
56EAA22E1901718F78C6DBB4 /* libPods-SignalTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1B5E7D6C9007F5E5761D79DD /* libPods-SignalTests.a */; };
701231B518ECAA4500D456C4 /* EvpMessageDigest.m in Sources */ = {isa = PBXBuildFile; fileRef = 701231B418ECAA4500D456C4 /* EvpMessageDigest.m */; };
70377AAB1918450100CAF501 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70377AAA1918450100CAF501 /* MobileCoreServices.framework */; };
7038632718F70C0700D4A43F /* CryptoTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 7038632418F70C0700D4A43F /* CryptoTools.m */; };
7038632818F70C0700D4A43F /* EvpSymetricUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 7038632618F70C0700D4A43F /* EvpSymetricUtil.m */; };
70B8FEE21909FE360042E3F0 /* 171756__nenadsimic__picked-coin-echo-2.wav in Resources */ = {isa = PBXBuildFile; fileRef = 70B8FEE11909FE360042E3F0 /* 171756__nenadsimic__picked-coin-echo-2.wav */; };
768A1A2B17FC9CD300E00ED8 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 768A1A2A17FC9CD300E00ED8 /* libz.dylib */; };
76C87F19181EFCE600C4ACAB /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76C87F18181EFCE600C4ACAB /* MediaPlayer.framework */; };
@ -171,30 +169,11 @@
76EB058218170B33006006FC /* Environment.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB041318170B33006006FC /* Environment.m */; };
76EB058818170B33006006FC /* PropertyListPreferences.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB041918170B33006006FC /* PropertyListPreferences.m */; };
76EB058A18170B33006006FC /* Release.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB041B18170B33006006FC /* Release.m */; };
76EB060C18170B33006006FC /* CategorizingLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04B318170B33006006FC /* CategorizingLogger.m */; };
76EB060E18170B33006006FC /* DecayingSampleEstimator.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04B518170B33006006FC /* DecayingSampleEstimator.m */; };
76EB061018170B33006006FC /* EventWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04B718170B33006006FC /* EventWindow.m */; };
76EB061218170B33006006FC /* LoggingUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04B918170B33006006FC /* LoggingUtil.m */; };
76EB061418170B33006006FC /* AnonymousConditionLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04C018170B33006006FC /* AnonymousConditionLogger.m */; };
76EB061618170B33006006FC /* AnonymousOccurrenceLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04C218170B33006006FC /* AnonymousOccurrenceLogger.m */; };
76EB061818170B33006006FC /* AnonymousValueLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04C418170B33006006FC /* AnonymousValueLogger.m */; };
76EB061A18170B33006006FC /* DiscardingLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04C618170B33006006FC /* DiscardingLog.m */; };
76EB061C18170B33006006FC /* ArrayUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04CA18170B33006006FC /* ArrayUtil.m */; };
76EB062218170B33006006FC /* CyclicalBuffer.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04D118170B33006006FC /* CyclicalBuffer.m */; };
76EB062418170B33006006FC /* PriorityQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04D318170B33006006FC /* PriorityQueue.m */; };
76EB062618170B33006006FC /* Queue.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04D518170B33006006FC /* Queue.m */; };
76EB063018170B33006006FC /* Conversions.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04E118170B33006006FC /* Conversions.m */; };
76EB063218170B33006006FC /* Crc32.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04E318170B33006006FC /* Crc32.m */; };
76EB063618170B33006006FC /* DataUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04E718170B33006006FC /* DataUtil.m */; };
76EB063818170B33006006FC /* DictionaryUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04E918170B33006006FC /* DictionaryUtil.m */; };
76EB063A18170B33006006FC /* FunctionalUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04EB18170B33006006FC /* FunctionalUtil.m */; };
76EB063C18170B33006006FC /* NumberUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04ED18170B33006006FC /* NumberUtil.m */; };
76EB063E18170B33006006FC /* Operation.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04EF18170B33006006FC /* Operation.m */; };
76EB064018170B33006006FC /* AnonymousTerminator.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04F418170B33006006FC /* AnonymousTerminator.m */; };
76EB064218170B33006006FC /* StringUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04F618170B33006006FC /* StringUtil.m */; };
76EB064418170B33006006FC /* ThreadManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04F818170B33006006FC /* ThreadManager.m */; };
76EB064618170B33006006FC /* TimeUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04FA18170B33006006FC /* TimeUtil.m */; };
76EB064818170B33006006FC /* Zid.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04FD18170B33006006FC /* Zid.m */; };
76EB068618170B34006006FC /* ContactTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB052F18170B33006006FC /* ContactTableViewCell.m */; };
954AEE6A1DF33E01002E5410 /* ContactsPickerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954AEE681DF33D32002E5410 /* ContactsPickerTest.swift */; };
A10FDF79184FB4BB007FF963 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76C87F18181EFCE600C4ACAB /* MediaPlayer.framework */; };
@ -241,26 +220,17 @@
B633C5CE1A1D190B0059AC12 /* quit@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C54C1A1D190B0059AC12 /* quit@2x.png */; };
B633C5D21A1D190B0059AC12 /* savephoto@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5501A1D190B0059AC12 /* savephoto@2x.png */; };
B660F6BB1C29868000687D6E /* OWSContactsManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6761C29867F00687D6E /* OWSContactsManagerTest.m */; };
B660F6D01C29868000687D6E /* DecayingSampleEstimatorTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6991C29868000687D6E /* DecayingSampleEstimatorTest.m */; };
B660F6D11C29868000687D6E /* EventWindowTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F69A1C29868000687D6E /* EventWindowTest.m */; };
B660F6D21C29868000687D6E /* PushManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F69C1C29868000687D6E /* PushManagerTest.m */; };
B660F6D41C29868000687D6E /* whisperFake.cer in Resources */ = {isa = PBXBuildFile; fileRef = B660F69F1C29868000687D6E /* whisperFake.cer */; };
B660F6D51C29868000687D6E /* TestUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6A11C29868000687D6E /* TestUtil.m */; };
B660F6D61C29868000687D6E /* ConversionsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6A41C29868000687D6E /* ConversionsTest.m */; };
B660F6D71C29868000687D6E /* Crc32Test.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6A61C29868000687D6E /* Crc32Test.m */; };
B660F6D81C29868000687D6E /* CryptoToolsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6A71C29868000687D6E /* CryptoToolsTest.m */; };
B660F6D91C29868000687D6E /* CyclicalBufferTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6A91C29868000687D6E /* CyclicalBufferTest.m */; };
B660F6DA1C29868000687D6E /* ExceptionsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6AB1C29868000687D6E /* ExceptionsTest.m */; };
B660F6DB1C29868000687D6E /* FunctionalUtilTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6AD1C29868000687D6E /* FunctionalUtilTest.m */; };
B660F6DC1C29868000687D6E /* FutureUtilTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6AE1C29868000687D6E /* FutureUtilTest.m */; };
B660F6DD1C29868000687D6E /* ObservableTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6AF1C29868000687D6E /* ObservableTest.m */; };
B660F6DF1C29868000687D6E /* QueueTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6B21C29868000687D6E /* QueueTest.m */; };
B660F6E01C29868000687D6E /* UtilTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6B41C29868000687D6E /* UtilTest.m */; };
B660F7161C29988E00687D6E /* GroupContactsResult.m in Sources */ = {isa = PBXBuildFile; fileRef = B671B2451A93B238002BBD9D /* GroupContactsResult.m */; };
B660F7171C29988E00687D6E /* OWSContactsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB040918170B33006006FC /* OWSContactsManager.m */; };
B660F7181C29988E00687D6E /* CryptoTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 7038632418F70C0700D4A43F /* CryptoTools.m */; };
B660F7191C29988E00687D6E /* EvpMessageDigest.m in Sources */ = {isa = PBXBuildFile; fileRef = 701231B418ECAA4500D456C4 /* EvpMessageDigest.m */; };
B660F71A1C29988E00687D6E /* EvpSymetricUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 7038632618F70C0700D4A43F /* EvpSymetricUtil.m */; };
B660F71B1C29988E00687D6E /* Environment.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB041318170B33006006FC /* Environment.m */; };
B660F71C1C29988E00687D6E /* DebugLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = B6C93C4D199567AD00EDF894 /* DebugLogger.m */; };
B660F71F1C29988E00687D6E /* PropertyListPreferences.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB041918170B33006006FC /* PropertyListPreferences.m */; };
@ -268,40 +238,19 @@
B660F7211C29988E00687D6E /* SignalKeyingStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B1013B196D213F007E3930 /* SignalKeyingStorage.m */; };
B660F7221C29988E00687D6E /* VersionMigrations.m in Sources */ = {isa = PBXBuildFile; fileRef = B60C16641988999D00E97A6C /* VersionMigrations.m */; };
B660F7561C29988E00687D6E /* PushManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B9ECFB198B31BA00C620D3 /* PushManager.m */; };
B660F7681C29988E00687D6E /* CategorizingLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04B318170B33006006FC /* CategorizingLogger.m */; };
B660F7691C29988E00687D6E /* DecayingSampleEstimator.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04B518170B33006006FC /* DecayingSampleEstimator.m */; };
B660F76A1C29988E00687D6E /* EventWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04B718170B33006006FC /* EventWindow.m */; };
B660F76B1C29988E00687D6E /* LoggingUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04B918170B33006006FC /* LoggingUtil.m */; };
B660F76C1C29988E00687D6E /* AnonymousConditionLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04C018170B33006006FC /* AnonymousConditionLogger.m */; };
B660F76D1C29988E00687D6E /* AnonymousOccurrenceLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04C218170B33006006FC /* AnonymousOccurrenceLogger.m */; };
B660F76E1C29988E00687D6E /* AnonymousValueLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04C418170B33006006FC /* AnonymousValueLogger.m */; };
B660F76F1C29988E00687D6E /* DiscardingLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04C618170B33006006FC /* DiscardingLog.m */; };
B660F7701C29988E00687D6E /* FLAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = B68EF9B71C0B1EBD009C3DCD /* FLAnimatedImage.m */; };
B660F7711C29988E00687D6E /* FLAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = B68EF9B91C0B1EBD009C3DCD /* FLAnimatedImageView.m */; };
B660F7721C29988E00687D6E /* AppStoreRating.m in Sources */ = {isa = PBXBuildFile; fileRef = B6DA6B061B8A2F9A00CA6F98 /* AppStoreRating.m */; };
B660F7751C29988E00687D6E /* UIColor+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = FCFA64B31A24F3880007FB87 /* UIColor+OWS.m */; };
B660F7761C29988E00687D6E /* UIFont+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = FCFA64B61A24F6730007FB87 /* UIFont+OWS.m */; };
B660F7771C29988E00687D6E /* UIImage+normalizeImage.m in Sources */ = {isa = PBXBuildFile; fileRef = B68112E91A4D9EC400BA82FF /* UIImage+normalizeImage.m */; };
B660F7781C29988E00687D6E /* ArrayUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04CA18170B33006006FC /* ArrayUtil.m */; };
B660F7791C29988E00687D6E /* CyclicalBuffer.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04D118170B33006006FC /* CyclicalBuffer.m */; };
B660F77A1C29988E00687D6E /* PriorityQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04D318170B33006006FC /* PriorityQueue.m */; };
B660F77B1C29988E00687D6E /* Queue.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04D518170B33006006FC /* Queue.m */; };
B660F77C1C29988E00687D6E /* Conversions.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04E118170B33006006FC /* Conversions.m */; };
B660F77D1C29988E00687D6E /* Crc32.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04E318170B33006006FC /* Crc32.m */; };
B660F77E1C29988E00687D6E /* DataUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04E718170B33006006FC /* DataUtil.m */; };
B660F77F1C29988E00687D6E /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; };
B660F7801C29988E00687D6E /* DictionaryUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04E918170B33006006FC /* DictionaryUtil.m */; };
B660F7811C29988E00687D6E /* FunctionalUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04EB18170B33006006FC /* FunctionalUtil.m */; };
B660F7821C29988E00687D6E /* FutureUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = BFB074C419A5611000F2947C /* FutureUtil.m */; };
B660F7831C29988E00687D6E /* NumberUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04ED18170B33006006FC /* NumberUtil.m */; };
B660F7841C29988E00687D6E /* ObservableValue.m in Sources */ = {isa = PBXBuildFile; fileRef = BFB074C619A5611000F2947C /* ObservableValue.m */; };
B660F7851C29988E00687D6E /* Operation.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04EF18170B33006006FC /* Operation.m */; };
B660F7861C29988E00687D6E /* AnonymousTerminator.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04F418170B33006006FC /* AnonymousTerminator.m */; };
B660F7871C29988E00687D6E /* StringUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04F618170B33006006FC /* StringUtil.m */; };
B660F7881C29988E00687D6E /* ThreadManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04F818170B33006006FC /* ThreadManager.m */; };
B660F7891C29988E00687D6E /* TimeUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04FA18170B33006006FC /* TimeUtil.m */; };
B660F78A1C29988E00687D6E /* UIUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B97940261832BD2400BD66CB /* UIUtil.m */; };
B660F78B1C29988E00687D6E /* Zid.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB04FD18170B33006006FC /* Zid.m */; };
B660F78C1C29988E00687D6E /* UIDevice+TSHardwareVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = FCC81A971A44558300DFEC7D /* UIDevice+TSHardwareVersion.m */; };
B66B9F721AEA6D1100E2E609 /* NotificationSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B66B9F711AEA6D1100E2E609 /* NotificationSettingsViewController.m */; };
B66B9F7D1AEAF40500E2E609 /* NotificationSettingsOptionsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B66B9F7C1AEAF40500E2E609 /* NotificationSettingsOptionsViewController.m */; };
@ -326,7 +275,6 @@
B97940271832BD2400BD66CB /* UIUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B97940261832BD2400BD66CB /* UIUtil.m */; };
B97CBFA818860EA3008E0DE9 /* CountryCodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B97CBFA618860EA3008E0DE9 /* CountryCodeViewController.m */; };
B9EB5ABD1884C002007CBB57 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9EB5ABC1884C002007CBB57 /* MessageUI.framework */; };
BFB074C719A5611000F2947C /* FutureUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = BFB074C419A5611000F2947C /* FutureUtil.m */; };
BFB074C919A5611000F2947C /* ObservableValue.m in Sources */ = {isa = PBXBuildFile; fileRef = BFB074C619A5611000F2947C /* ObservableValue.m */; };
D202868116DBE0E7009068E9 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2AEACDB16C426DA00C364C0 /* CFNetwork.framework */; };
D202868216DBE0F4009068E9 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2179CFD16BB0B480006F3AB /* SystemConfiguration.framework */; };
@ -448,7 +396,6 @@
452ECA4C1E087E7200E2F016 /* MessageFetcherJob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MessageFetcherJob.swift; path = Jobs/MessageFetcherJob.swift; sourceTree = "<group>"; };
4531C9C21DD8E6D800F08304 /* JSQMessagesCollectionViewCell+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "JSQMessagesCollectionViewCell+OWS.h"; sourceTree = "<group>"; };
4531C9C31DD8E6D800F08304 /* JSQMessagesCollectionViewCell+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "JSQMessagesCollectionViewCell+OWS.m"; sourceTree = "<group>"; };
453201241E71100C00F20761 /* DisplayableTextFilter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayableTextFilter.swift; sourceTree = "<group>"; };
45387B021E36D650005D00B3 /* OWS102MoveLoggingPreferenceToUserDefaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWS102MoveLoggingPreferenceToUserDefaults.h; path = Migrations/OWS102MoveLoggingPreferenceToUserDefaults.h; sourceTree = "<group>"; };
45387B031E36D650005D00B3 /* OWS102MoveLoggingPreferenceToUserDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWS102MoveLoggingPreferenceToUserDefaults.m; path = Migrations/OWS102MoveLoggingPreferenceToUserDefaults.m; sourceTree = "<group>"; };
453CC0361D08E1A60040EBA3 /* sn */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sn; path = translations/sn.lproj/Localizable.strings; sourceTree = "<group>"; };
@ -532,6 +479,7 @@
45E282DF1D08E6CC00ADD4C8 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = translations/id.lproj/Localizable.strings; sourceTree = "<group>"; };
45E2E91E1E13EE3500457AA0 /* OWSCallNotificationsAdaptee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWSCallNotificationsAdaptee.h; path = UserInterface/OWSCallNotificationsAdaptee.h; sourceTree = "<group>"; };
45E2E91F1E153B3D00457AA0 /* Strings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Strings.swift; path = UserInterface/Strings.swift; sourceTree = "<group>"; };
45E615151E8C590B0018AD52 /* DisplayableTextFilter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayableTextFilter.swift; sourceTree = "<group>"; };
45E7A6A61E71CA7E00D44FB5 /* DisplayableTextFilterTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayableTextFilterTest.swift; sourceTree = "<group>"; };
45EB32CD1D7465C900735B2E /* OWSLinkedDevicesTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSLinkedDevicesTableViewController.h; sourceTree = "<group>"; };
45EB32CE1D7465C900735B2E /* OWSLinkedDevicesTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSLinkedDevicesTableViewController.m; sourceTree = "<group>"; };
@ -552,15 +500,10 @@
45FBC5D01DF8592E00E9B410 /* SignalCall.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalCall.swift; sourceTree = "<group>"; };
4CE0E3751B95453C007210CF /* TSAnimatedAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSAnimatedAdapter.h; sourceTree = "<group>"; };
4CE0E3761B954546007210CF /* TSAnimatedAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAnimatedAdapter.m; sourceTree = "<group>"; };
701231B318ECAA4500D456C4 /* EvpMessageDigest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EvpMessageDigest.h; sourceTree = "<group>"; };
701231B418ECAA4500D456C4 /* EvpMessageDigest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EvpMessageDigest.m; sourceTree = "<group>"; };
70377AAA1918450100CAF501 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
7038632318F70C0700D4A43F /* CryptoTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoTools.h; sourceTree = "<group>"; };
7038632418F70C0700D4A43F /* CryptoTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CryptoTools.m; sourceTree = "<group>"; };
7038632518F70C0700D4A43F /* EvpSymetricUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EvpSymetricUtil.h; sourceTree = "<group>"; };
7038632618F70C0700D4A43F /* EvpSymetricUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EvpSymetricUtil.m; sourceTree = "<group>"; };
70B8FEE11909FE360042E3F0 /* 171756__nenadsimic__picked-coin-echo-2.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = "171756__nenadsimic__picked-coin-echo-2.wav"; sourceTree = "<group>"; };
70E803ED18F6DD1400BF77BC /* EvpUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EvpUtil.h; sourceTree = "<group>"; };
768A1A2A17FC9CD300E00ED8 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
76C87F18181EFCE600C4ACAB /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };
76EB03C218170B33006006FC /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
@ -573,60 +516,17 @@
76EB041918170B33006006FC /* PropertyListPreferences.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PropertyListPreferences.m; sourceTree = "<group>"; };
76EB041A18170B33006006FC /* Release.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Release.h; sourceTree = "<group>"; };
76EB041B18170B33006006FC /* Release.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Release.m; sourceTree = "<group>"; };
76EB04B218170B33006006FC /* CategorizingLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CategorizingLogger.h; sourceTree = "<group>"; };
76EB04B318170B33006006FC /* CategorizingLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CategorizingLogger.m; sourceTree = "<group>"; };
76EB04B418170B33006006FC /* DecayingSampleEstimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DecayingSampleEstimator.h; sourceTree = "<group>"; };
76EB04B518170B33006006FC /* DecayingSampleEstimator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DecayingSampleEstimator.m; sourceTree = "<group>"; };
76EB04B618170B33006006FC /* EventWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventWindow.h; sourceTree = "<group>"; };
76EB04B718170B33006006FC /* EventWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EventWindow.m; sourceTree = "<group>"; };
76EB04B818170B33006006FC /* LoggingUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoggingUtil.h; sourceTree = "<group>"; };
76EB04B918170B33006006FC /* LoggingUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LoggingUtil.m; sourceTree = "<group>"; };
76EB04BB18170B33006006FC /* ConditionLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConditionLogger.h; sourceTree = "<group>"; };
76EB04BC18170B33006006FC /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = "<group>"; };
76EB04BD18170B33006006FC /* OccurrenceLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OccurrenceLogger.h; sourceTree = "<group>"; };
76EB04BF18170B33006006FC /* AnonymousConditionLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnonymousConditionLogger.h; sourceTree = "<group>"; };
76EB04C018170B33006006FC /* AnonymousConditionLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnonymousConditionLogger.m; sourceTree = "<group>"; };
76EB04C118170B33006006FC /* AnonymousOccurrenceLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnonymousOccurrenceLogger.h; sourceTree = "<group>"; };
76EB04C218170B33006006FC /* AnonymousOccurrenceLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnonymousOccurrenceLogger.m; sourceTree = "<group>"; };
76EB04C318170B33006006FC /* AnonymousValueLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnonymousValueLogger.h; sourceTree = "<group>"; };
76EB04C418170B33006006FC /* AnonymousValueLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnonymousValueLogger.m; sourceTree = "<group>"; };
76EB04C518170B33006006FC /* DiscardingLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiscardingLog.h; sourceTree = "<group>"; };
76EB04C618170B33006006FC /* DiscardingLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DiscardingLog.m; sourceTree = "<group>"; };
76EB04C718170B33006006FC /* ValueLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueLogger.h; sourceTree = "<group>"; };
76EB04C918170B33006006FC /* ArrayUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayUtil.h; sourceTree = "<group>"; };
76EB04CA18170B33006006FC /* ArrayUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ArrayUtil.m; sourceTree = "<group>"; };
76EB04D018170B33006006FC /* CyclicalBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CyclicalBuffer.h; sourceTree = "<group>"; };
76EB04D118170B33006006FC /* CyclicalBuffer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CyclicalBuffer.m; sourceTree = "<group>"; };
76EB04D218170B33006006FC /* PriorityQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PriorityQueue.h; sourceTree = "<group>"; };
76EB04D318170B33006006FC /* PriorityQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PriorityQueue.m; sourceTree = "<group>"; };
76EB04D418170B33006006FC /* Queue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Queue.h; sourceTree = "<group>"; };
76EB04D518170B33006006FC /* Queue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Queue.m; sourceTree = "<group>"; };
76EB04E018170B33006006FC /* Conversions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Conversions.h; sourceTree = "<group>"; };
76EB04E118170B33006006FC /* Conversions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Conversions.m; sourceTree = "<group>"; };
76EB04E218170B33006006FC /* Crc32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Crc32.h; sourceTree = "<group>"; };
76EB04E318170B33006006FC /* Crc32.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Crc32.m; sourceTree = "<group>"; };
76EB04E618170B33006006FC /* DataUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataUtil.h; sourceTree = "<group>"; };
76EB04E718170B33006006FC /* DataUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataUtil.m; sourceTree = "<group>"; };
76EB04E818170B33006006FC /* DictionaryUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DictionaryUtil.h; sourceTree = "<group>"; };
76EB04E918170B33006006FC /* DictionaryUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DictionaryUtil.m; sourceTree = "<group>"; };
76EB04EA18170B33006006FC /* FunctionalUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionalUtil.h; sourceTree = "<group>"; };
76EB04EB18170B33006006FC /* FunctionalUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FunctionalUtil.m; sourceTree = "<group>"; };
76EB04EC18170B33006006FC /* NumberUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NumberUtil.h; sourceTree = "<group>"; };
76EB04ED18170B33006006FC /* NumberUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NumberUtil.m; sourceTree = "<group>"; };
76EB04EE18170B33006006FC /* Operation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Operation.h; sourceTree = "<group>"; };
76EB04EF18170B33006006FC /* Operation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Operation.m; sourceTree = "<group>"; };
76EB04F118170B33006006FC /* Terminable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Terminable.h; sourceTree = "<group>"; };
76EB04F318170B33006006FC /* AnonymousTerminator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnonymousTerminator.h; sourceTree = "<group>"; };
76EB04F418170B33006006FC /* AnonymousTerminator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnonymousTerminator.m; sourceTree = "<group>"; };
76EB04F518170B33006006FC /* StringUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringUtil.h; sourceTree = "<group>"; };
76EB04F618170B33006006FC /* StringUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StringUtil.m; sourceTree = "<group>"; };
76EB04F718170B33006006FC /* ThreadManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadManager.h; sourceTree = "<group>"; };
76EB04F818170B33006006FC /* ThreadManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThreadManager.m; sourceTree = "<group>"; };
76EB04F918170B33006006FC /* TimeUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeUtil.h; sourceTree = "<group>"; };
76EB04FA18170B33006006FC /* TimeUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TimeUtil.m; sourceTree = "<group>"; };
76EB04FB18170B33006006FC /* Util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Util.h; sourceTree = "<group>"; };
76EB04FC18170B33006006FC /* Zid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Zid.h; sourceTree = "<group>"; };
76EB04FD18170B33006006FC /* Zid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Zid.m; sourceTree = "<group>"; };
76EB052E18170B33006006FC /* ContactTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactTableViewCell.h; sourceTree = "<group>"; };
76EB052F18170B33006006FC /* ContactTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactTableViewCell.m; sourceTree = "<group>"; };
7DB8EE72F8522189E3E2CB45 /* libPods-Signal.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Signal.a"; sourceTree = BUILT_PRODUCTS_DIR; };
@ -688,25 +588,15 @@
B646D1151AA5467E004133BA /* it_IT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it_IT; path = translations/it_IT.lproj/Localizable.strings; sourceTree = "<group>"; };
B657DDC91911A40500F45B0C /* Signal.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Signal.entitlements; sourceTree = "<group>"; };
B660F6761C29867F00687D6E /* OWSContactsManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactsManagerTest.m; sourceTree = "<group>"; };
B660F6991C29868000687D6E /* DecayingSampleEstimatorTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DecayingSampleEstimatorTest.m; sourceTree = "<group>"; };
B660F69A1C29868000687D6E /* EventWindowTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EventWindowTest.m; sourceTree = "<group>"; };
B660F69C1C29868000687D6E /* PushManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PushManagerTest.m; sourceTree = "<group>"; };
B660F69E1C29868000687D6E /* SignalTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SignalTests-Info.plist"; sourceTree = "<group>"; };
B660F69F1C29868000687D6E /* whisperFake.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = whisperFake.cer; sourceTree = "<group>"; };
B660F6A01C29868000687D6E /* TestUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestUtil.h; sourceTree = "<group>"; };
B660F6A11C29868000687D6E /* TestUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestUtil.m; sourceTree = "<group>"; };
B660F6A31C29868000687D6E /* ConversionsTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConversionsTest.h; sourceTree = "<group>"; };
B660F6A41C29868000687D6E /* ConversionsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConversionsTest.m; sourceTree = "<group>"; };
B660F6A51C29868000687D6E /* Crc32Test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Crc32Test.h; sourceTree = "<group>"; };
B660F6A61C29868000687D6E /* Crc32Test.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Crc32Test.m; sourceTree = "<group>"; };
B660F6A71C29868000687D6E /* CryptoToolsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CryptoToolsTest.m; sourceTree = "<group>"; };
B660F6A81C29868000687D6E /* CyclicalBufferTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CyclicalBufferTest.h; sourceTree = "<group>"; };
B660F6A91C29868000687D6E /* CyclicalBufferTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CyclicalBufferTest.m; sourceTree = "<group>"; };
B660F6AA1C29868000687D6E /* ExceptionsTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExceptionsTest.h; sourceTree = "<group>"; };
B660F6AB1C29868000687D6E /* ExceptionsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExceptionsTest.m; sourceTree = "<group>"; };
B660F6AC1C29868000687D6E /* FunctionalUtilTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionalUtilTest.h; sourceTree = "<group>"; };
B660F6AD1C29868000687D6E /* FunctionalUtilTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FunctionalUtilTest.m; sourceTree = "<group>"; };
B660F6AE1C29868000687D6E /* FutureUtilTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FutureUtilTest.m; sourceTree = "<group>"; };
B660F6AF1C29868000687D6E /* ObservableTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObservableTest.m; sourceTree = "<group>"; };
B660F6B11C29868000687D6E /* QueueTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QueueTest.h; sourceTree = "<group>"; };
B660F6B21C29868000687D6E /* QueueTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QueueTest.m; sourceTree = "<group>"; };
@ -773,8 +663,6 @@
B97CBFA518860EA3008E0DE9 /* CountryCodeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CountryCodeViewController.h; sourceTree = "<group>"; };
B97CBFA618860EA3008E0DE9 /* CountryCodeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CountryCodeViewController.m; sourceTree = "<group>"; };
B9EB5ABC1884C002007CBB57 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; };
BFB074C319A5611000F2947C /* FutureUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FutureUtil.h; sourceTree = "<group>"; };
BFB074C419A5611000F2947C /* FutureUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FutureUtil.m; sourceTree = "<group>"; };
BFB074C519A5611000F2947C /* ObservableValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObservableValue.h; sourceTree = "<group>"; };
BFB074C619A5611000F2947C /* ObservableValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObservableValue.m; sourceTree = "<group>"; };
D2179CFB16BB0B3A0006F3AB /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; };
@ -1091,11 +979,6 @@
children = (
7038632318F70C0700D4A43F /* CryptoTools.h */,
7038632418F70C0700D4A43F /* CryptoTools.m */,
701231B318ECAA4500D456C4 /* EvpMessageDigest.h */,
701231B418ECAA4500D456C4 /* EvpMessageDigest.m */,
7038632518F70C0700D4A43F /* EvpSymetricUtil.h */,
7038632618F70C0700D4A43F /* EvpSymetricUtil.m */,
70E803ED18F6DD1400BF77BC /* EvpUtil.h */,
);
path = crypto;
sourceTree = "<group>";
@ -1111,7 +994,6 @@
70DBA29918CFE98500771DAD /* crypto */,
76EB041118170B33006006FC /* environment */,
76EB041D18170B33006006FC /* network */,
76EB04B118170B33006006FC /* profiling */,
B60959791C2C0FA9004E8797 /* rating */,
76EB04C818170B33006006FC /* util */,
45D231751DC7E8C50034FA89 /* Jobs */,
@ -1192,73 +1074,18 @@
path = "../phone/signaling/number directory";
sourceTree = "<group>";
};
76EB04B118170B33006006FC /* profiling */ = {
isa = PBXGroup;
children = (
76EB04B218170B33006006FC /* CategorizingLogger.h */,
76EB04B318170B33006006FC /* CategorizingLogger.m */,
76EB04B418170B33006006FC /* DecayingSampleEstimator.h */,
76EB04B518170B33006006FC /* DecayingSampleEstimator.m */,
76EB04B618170B33006006FC /* EventWindow.h */,
76EB04B718170B33006006FC /* EventWindow.m */,
76EB04B818170B33006006FC /* LoggingUtil.h */,
76EB04B918170B33006006FC /* LoggingUtil.m */,
76EB04BA18170B33006006FC /* protocols */,
);
path = profiling;
sourceTree = "<group>";
};
76EB04BA18170B33006006FC /* protocols */ = {
isa = PBXGroup;
children = (
76EB04BB18170B33006006FC /* ConditionLogger.h */,
76EB04BC18170B33006006FC /* Logging.h */,
76EB04BD18170B33006006FC /* OccurrenceLogger.h */,
76EB04BE18170B33006006FC /* utilities */,
76EB04C718170B33006006FC /* ValueLogger.h */,
);
path = protocols;
sourceTree = "<group>";
};
76EB04BE18170B33006006FC /* utilities */ = {
isa = PBXGroup;
children = (
76EB04BF18170B33006006FC /* AnonymousConditionLogger.h */,
76EB04C018170B33006006FC /* AnonymousConditionLogger.m */,
76EB04C118170B33006006FC /* AnonymousOccurrenceLogger.h */,
76EB04C218170B33006006FC /* AnonymousOccurrenceLogger.m */,
76EB04C318170B33006006FC /* AnonymousValueLogger.h */,
76EB04C418170B33006006FC /* AnonymousValueLogger.m */,
76EB04C518170B33006006FC /* DiscardingLog.h */,
76EB04C618170B33006006FC /* DiscardingLog.m */,
);
path = utilities;
sourceTree = "<group>";
};
76EB04C818170B33006006FC /* util */ = {
isa = PBXGroup;
children = (
B68EF9B51C0B1E7D009C3DCD /* Animated GIFS */,
B6DA6B051B8A2F9A00CA6F98 /* AppStoreRating.h */,
B6DA6B061B8A2F9A00CA6F98 /* AppStoreRating.m */,
76EB04C918170B33006006FC /* ArrayUtil.h */,
76EB04CA18170B33006006FC /* ArrayUtil.m */,
76EB04CF18170B33006006FC /* collections */,
76EB04E018170B33006006FC /* Conversions.h */,
76EB04E118170B33006006FC /* Conversions.m */,
76EB04E218170B33006006FC /* Crc32.h */,
76EB04E318170B33006006FC /* Crc32.m */,
76EB04E618170B33006006FC /* DataUtil.h */,
76EB04E718170B33006006FC /* DataUtil.m */,
B90418E4183E9DD40038554A /* DateUtil.h */,
B90418E5183E9DD40038554A /* DateUtil.m */,
76EB04E818170B33006006FC /* DictionaryUtil.h */,
76EB04E918170B33006006FC /* DictionaryUtil.m */,
453201241E71100C00F20761 /* DisplayableTextFilter.swift */,
45E615151E8C590B0018AD52 /* DisplayableTextFilter.swift */,
76EB04EA18170B33006006FC /* FunctionalUtil.h */,
76EB04EB18170B33006006FC /* FunctionalUtil.m */,
BFB074C319A5611000F2947C /* FutureUtil.h */,
BFB074C419A5611000F2947C /* FutureUtil.m */,
B62F5E0E1C2980B4000D370C /* NSData+ows_StripToken.h */,
B62F5E0F1C2980B4000D370C /* NSData+ows_StripToken.m */,
76EB04EC18170B33006006FC /* NumberUtil.h */,
@ -1274,15 +1101,10 @@
4579431C1E7C8CE9008ED0C0 /* Pastelog.h */,
4579431D1E7C8CE9008ED0C0 /* Pastelog.m */,
450DF2041E0D74AC003D14BE /* Platform.swift */,
76EB04F018170B33006006FC /* protocols */,
76EB04F518170B33006006FC /* StringUtil.h */,
76EB04F618170B33006006FC /* StringUtil.m */,
76EB04F718170B33006006FC /* ThreadManager.h */,
76EB04F818170B33006006FC /* ThreadManager.m */,
345670FF1E89A5F1006EE662 /* ThreadUtil.h */,
345671001E89A5F1006EE662 /* ThreadUtil.m */,
76EB04F918170B33006006FC /* TimeUtil.h */,
76EB04FA18170B33006006FC /* TimeUtil.m */,
FCFA64B11A24F29E0007FB87 /* UI Categories */,
FCC81A961A44558300DFEC7D /* UIDevice+TSHardwareVersion.h */,
FCC81A971A44558300DFEC7D /* UIDevice+TSHardwareVersion.m */,
@ -1291,8 +1113,6 @@
76EB04FB18170B33006006FC /* Util.h */,
45F170D51E315310003FC1F2 /* Weak.swift */,
45F170CB1E310E22003FC1F2 /* WeakTimer.swift */,
76EB04FC18170B33006006FC /* Zid.h */,
76EB04FD18170B33006006FC /* Zid.m */,
);
path = util;
sourceTree = "<group>";
@ -1300,34 +1120,12 @@
76EB04CF18170B33006006FC /* collections */ = {
isa = PBXGroup;
children = (
76EB04D018170B33006006FC /* CyclicalBuffer.h */,
76EB04D118170B33006006FC /* CyclicalBuffer.m */,
76EB04D218170B33006006FC /* PriorityQueue.h */,
76EB04D318170B33006006FC /* PriorityQueue.m */,
76EB04D418170B33006006FC /* Queue.h */,
76EB04D518170B33006006FC /* Queue.m */,
);
path = collections;
sourceTree = "<group>";
};
76EB04F018170B33006006FC /* protocols */ = {
isa = PBXGroup;
children = (
76EB04F118170B33006006FC /* Terminable.h */,
76EB04F218170B33006006FC /* utilities */,
);
path = protocols;
sourceTree = "<group>";
};
76EB04F218170B33006006FC /* utilities */ = {
isa = PBXGroup;
children = (
76EB04F318170B33006006FC /* AnonymousTerminator.h */,
76EB04F418170B33006006FC /* AnonymousTerminator.m */,
);
path = utilities;
sourceTree = "<group>";
};
76EB04FE18170B33006006FC /* View Controllers */ = {
isa = PBXGroup;
children = (
@ -1486,11 +1284,9 @@
459C3F0E1C9B3A20003ACF51 /* TSMessageAdapters */,
B660F6731C29867F00687D6E /* call */,
B660F6751C29867F00687D6E /* contact */,
B660F6981C29868000687D6E /* profiling */,
B660F69B1C29868000687D6E /* push */,
B660F69D1C29868000687D6E /* Supporting Files */,
B660F6A01C29868000687D6E /* TestUtil.h */,
B660F6A11C29868000687D6E /* TestUtil.m */,
B660F6A21C29868000687D6E /* util */,
);
path = test;
@ -1515,15 +1311,6 @@
path = contact;
sourceTree = "<group>";
};
B660F6981C29868000687D6E /* profiling */ = {
isa = PBXGroup;
children = (
B660F6991C29868000687D6E /* DecayingSampleEstimatorTest.m */,
B660F69A1C29868000687D6E /* EventWindowTest.m */,
);
path = profiling;
sourceTree = "<group>";
};
B660F69B1C29868000687D6E /* push */ = {
isa = PBXGroup;
children = (
@ -1545,18 +1332,11 @@
isa = PBXGroup;
children = (
45E7A6A61E71CA7E00D44FB5 /* DisplayableTextFilterTest.swift */,
B660F6A31C29868000687D6E /* ConversionsTest.h */,
B660F6A41C29868000687D6E /* ConversionsTest.m */,
B660F6A51C29868000687D6E /* Crc32Test.h */,
B660F6A61C29868000687D6E /* Crc32Test.m */,
B660F6A71C29868000687D6E /* CryptoToolsTest.m */,
B660F6A81C29868000687D6E /* CyclicalBufferTest.h */,
B660F6A91C29868000687D6E /* CyclicalBufferTest.m */,
B660F6AA1C29868000687D6E /* ExceptionsTest.h */,
B660F6AB1C29868000687D6E /* ExceptionsTest.m */,
B660F6AC1C29868000687D6E /* FunctionalUtilTest.h */,
B660F6AD1C29868000687D6E /* FunctionalUtilTest.m */,
B660F6AE1C29868000687D6E /* FutureUtilTest.m */,
B660F6AF1C29868000687D6E /* ObservableTest.m */,
B660F6B11C29868000687D6E /* QueueTest.h */,
B660F6B21C29868000687D6E /* QueueTest.m */,
@ -2155,19 +1935,15 @@
76EB063E18170B33006006FC /* Operation.m in Sources */,
A5509ECD1A69B1D600ABA4BC /* CountryCodeTableViewCell.m in Sources */,
45C9DEB81DF4E35A0065CA84 /* WebRTCCallMessageHandler.swift in Sources */,
76EB061218170B33006006FC /* LoggingUtil.m in Sources */,
76EB060E18170B33006006FC /* DecayingSampleEstimator.m in Sources */,
340757C21E5602D6001F15DD /* AttachmentSharing.m in Sources */,
4505C2C21E648F7A00CEBF41 /* ExperienceUpgradeFinder.swift in Sources */,
344F2F671E57A932000D9322 /* UIViewController+OWS.m in Sources */,
B6DA6B071B8A2F9A00CA6F98 /* AppStoreRating.m in Sources */,
458E38311D6682450094BD24 /* OWSQRCodeScanningViewController.m in Sources */,
451A13B11E13DED2000A50FD /* CallNotificationsAdapter.swift in Sources */,
76EB062418170B33006006FC /* PriorityQueue.m in Sources */,
3456710A1E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m in Sources */,
450DF2091E0DD2C6003D14BE /* UserNotificationsAdaptee.swift in Sources */,
B6BADBE71B88D1AC0086A80D /* LockInteractionController.m in Sources */,
76EB061A18170B33006006FC /* DiscardingLog.m in Sources */,
45CD81F21DC03A22004C9430 /* OWSLogger.m in Sources */,
FCB11D931A12A4AA002F93FB /* FullImageViewController.m in Sources */,
B60C16651988999D00E97A6C /* VersionMigrations.m in Sources */,
@ -2180,7 +1956,6 @@
45387B041E36D650005D00B3 /* OWS102MoveLoggingPreferenceToUserDefaults.m in Sources */,
348A08511E6C73490057E290 /* AttachmentApprovalViewController.swift in Sources */,
EF764C351DB67CC5000D9A87 /* UIViewController+CameraPermissions.m in Sources */,
453201251E71100C00F20761 /* DisplayableTextFilter.swift in Sources */,
45CD81EF1DC030E7004C9430 /* AccountManager.swift in Sources */,
45794E861E00620000066731 /* CallUIAdapter.swift in Sources */,
FCFA64B71A24F6730007FB87 /* UIFont+OWS.m in Sources */,
@ -2191,17 +1966,13 @@
B62D53F71A23CCAD009AAF82 /* TSMessageAdapter.m in Sources */,
FCD274EB1A5AFDDB00202277 /* AboutTableViewController.m in Sources */,
FCFD257F1A154B2C00F4C644 /* RegistrationViewController.m in Sources */,
701231B518ECAA4500D456C4 /* EvpMessageDigest.m in Sources */,
76EB062218170B33006006FC /* CyclicalBuffer.m in Sources */,
76EB063C18170B33006006FC /* NumberUtil.m in Sources */,
B6A3EB4B1A423B3800B2236B /* TSPhotoAdapter.m in Sources */,
4509E79C1DD6545B0025A59F /* CallViewController.swift in Sources */,
34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */,
76EB063A18170B33006006FC /* FunctionalUtil.m in Sources */,
76EB060C18170B33006006FC /* CategorizingLogger.m in Sources */,
76EB058A18170B33006006FC /* Release.m in Sources */,
45D231771DC7E8F10034FA89 /* SessionResetJob.swift in Sources */,
76EB061018170B33006006FC /* EventWindow.m in Sources */,
450873C71D9D867B006B54F2 /* OWSIncomingMessageCollectionViewCell.m in Sources */,
76EB057A18170B33006006FC /* OWSContactsManager.m in Sources */,
76EB064218170B33006006FC /* StringUtil.m in Sources */,
@ -2211,17 +1982,14 @@
D221A09A169C9E5E00537ABF /* main.m in Sources */,
345671011E89A5F1006EE662 /* ThreadUtil.m in Sources */,
45843D1F1D2236B30013E85A /* OWSContactsSearcher.m in Sources */,
76EB061618170B33006006FC /* AnonymousOccurrenceLogger.m in Sources */,
450873C31D9D5149006B54F2 /* OWSExpirationTimerView.m in Sources */,
B6258B331C29E2E60014138E /* NotificationsManager.m in Sources */,
45666EC91D994C0D008FE134 /* OWSGroupAvatarBuilder.m in Sources */,
76EB063018170B33006006FC /* Conversions.m in Sources */,
FCAC963C19FEF9280046DFC5 /* SignalsViewController.m in Sources */,
345671231E8B1618006EE662 /* OversizeTextMessageViewController.swift in Sources */,
B66B9F7D1AEAF40500E2E609 /* NotificationSettingsOptionsViewController.m in Sources */,
76EB058218170B33006006FC /* Environment.m in Sources */,
45464DBC1DFA041F001D3FD6 /* DataChannelMessage.swift in Sources */,
76EB064418170B33006006FC /* ThreadManager.m in Sources */,
450DF2051E0D74AC003D14BE /* Platform.swift in Sources */,
45666F561D9B2827008FE134 /* OWSScrubbingLogFormatter.m in Sources */,
45C0DC1E1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */,
@ -2230,10 +1998,9 @@
A5D0699B1A50E9CB004CB540 /* ShowGroupMembersViewController.m in Sources */,
45855F371D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */,
FC31962D1A06A2190094C78E /* FingerprintViewController.m in Sources */,
76EB061418170B33006006FC /* AnonymousConditionLogger.m in Sources */,
FC3196301A0814130094C78E /* SettingsTableViewController.m in Sources */,
45666EC61D99483D008FE134 /* OWSAvatarBuilder.m in Sources */,
7038632818F70C0700D4A43F /* EvpSymetricUtil.m in Sources */,
45E615161E8C590B0018AD52 /* DisplayableTextFilter.swift in Sources */,
76EB068618170B34006006FC /* ContactTableViewCell.m in Sources */,
FCAC965119FF0A6E0046DFC5 /* MessagesViewController.m in Sources */,
34330AA31E79686200DF2FB9 /* OWSProgressView.m in Sources */,
@ -2250,17 +2017,13 @@
451764271DE939F300EDB8B9 /* ContactsPicker.swift in Sources */,
450573FE1E78A06D00615BB4 /* OWS103EnableVideoCalling.m in Sources */,
B6C93C4E199567AD00EDF894 /* DebugLogger.m in Sources */,
76EB063218170B33006006FC /* Crc32.m in Sources */,
45F659821E1BE77000444429 /* NonCallKitCallUIAdaptee.swift in Sources */,
458E38341D66873D0094BD24 /* OWSLinkDeviceViewController.m in Sources */,
76EB063618170B33006006FC /* DataUtil.m in Sources */,
45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */,
45C0DC1B1E68FE9000E04C47 /* UIApplication+frontmostViewController.swift in Sources */,
452E3C8E1D935C77002A45B0 /* OWSConversationSettingsTableViewController.m in Sources */,
34535D821E256BE9008A4747 /* UIView+OWS.m in Sources */,
76EB061818170B33006006FC /* AnonymousValueLogger.m in Sources */,
FC31962A1A067D8F0094C78E /* MessageComposeTableViewController.m in Sources */,
76EB061C18170B33006006FC /* ArrayUtil.m in Sources */,
FCD274E81A5AFDC900202277 /* AdvancedSettingsTableViewController.m in Sources */,
45F3AEB61DFDE7900080CE33 /* AvatarImageView.swift in Sources */,
7038632718F70C0700D4A43F /* CryptoTools.m in Sources */,
@ -2271,10 +2034,8 @@
452C468F1E427E200087B011 /* OutboundCallInitiator.swift in Sources */,
FCFD25821A154B3800F4C644 /* CodeVerificationViewController.m in Sources */,
453D28B71D32BA5F00D523F0 /* OWSDisplayedMessage.m in Sources */,
76EB064618170B33006006FC /* TimeUtil.m in Sources */,
45F170BB1E2FC5D3003FC1F2 /* CallAudioService.swift in Sources */,
FC4FA0261A1B9DC600DA100A /* SignalsNavigationController.m in Sources */,
76EB063818170B33006006FC /* DictionaryUtil.m in Sources */,
45EB32CF1D7465C900735B2E /* OWSLinkedDevicesTableViewController.m in Sources */,
45F659731E1BD99C00444429 /* CallKitCallUIAdaptee.swift in Sources */,
45BB93381E688E14001E3939 /* UIDevice+featureSupport.swift in Sources */,
@ -2291,7 +2052,6 @@
B68112EA1A4D9EC400BA82FF /* UIImage+normalizeImage.m in Sources */,
B609597C1C2C0FC6004E8797 /* iRate.m in Sources */,
4574A5D61DD6704700C6B692 /* CallService.swift in Sources */,
BFB074C719A5611000F2947C /* FutureUtil.m in Sources */,
45E1F3A51DEF20A100852CF1 /* NoSignalContactsView.swift in Sources */,
FCD274E21A5AFD8000202277 /* PrivacySettingsTableViewController.m in Sources */,
45F170D61E315310003FC1F2 /* Weak.swift in Sources */,
@ -2302,13 +2062,11 @@
45666F7E1D9C0814008FE134 /* OWSDatabaseMigrationRunner.m in Sources */,
4579431E1E7C8CE9008ED0C0 /* Pastelog.m in Sources */,
45C681BC1D305C080050903A /* OWSCallCollectionViewCell.m in Sources */,
76EB064018170B33006006FC /* AnonymousTerminator.m in Sources */,
76EB058818170B33006006FC /* PropertyListPreferences.m in Sources */,
34330A611E788EA900DF2FB9 /* AttachmentUploadView.m in Sources */,
45666F7B1D9C0533008FE134 /* OWSDatabaseMigration.m in Sources */,
B90418E6183E9DD40038554A /* DateUtil.m in Sources */,
45B201761DAECBFE00C461E0 /* HighlightableLabel.swift in Sources */,
76EB064818170B33006006FC /* Zid.m in Sources */,
459311FC1D75C948008DD4F0 /* OWSDeviceTableViewCell.m in Sources */,
34802DD71E899CFB0032EA1D /* DebugUITableViewController.m in Sources */,
);
@ -2332,8 +2090,6 @@
B660F7161C29988E00687D6E /* GroupContactsResult.m in Sources */,
B660F7171C29988E00687D6E /* OWSContactsManager.m in Sources */,
B660F7181C29988E00687D6E /* CryptoTools.m in Sources */,
B660F7191C29988E00687D6E /* EvpMessageDigest.m in Sources */,
B660F71A1C29988E00687D6E /* EvpSymetricUtil.m in Sources */,
B660F71B1C29988E00687D6E /* Environment.m in Sources */,
B660F71C1C29988E00687D6E /* DebugLogger.m in Sources */,
B660F71F1C29988E00687D6E /* PropertyListPreferences.m in Sources */,
@ -2349,7 +2105,6 @@
452D1EE81DCA90D100A57EC4 /* MesssagesBubblesSizeCalculatorTest.swift in Sources */,
45BFFFA91D898AF0004A12A7 /* OWSStaleNotificationObserver.m in Sources */,
45C681C71D305C9E0050903A /* OWSDisplayedMessageCollectionViewCell.m in Sources */,
45E7A6A91E71CC2E00D44FB5 /* DisplayableTextFilter.swift in Sources */,
451DE9FE1DC1A28200810E42 /* SyncPushTokensJob.swift in Sources */,
45F170AF1E2F0393003FC1F2 /* CallAudioSessionTest.swift in Sources */,
456F6E231E24133500FD2210 /* Platform.swift in Sources */,
@ -2364,16 +2119,8 @@
451A13B21E13DED2000A50FD /* CallNotificationsAdapter.swift in Sources */,
45C681B81D305A580050903A /* OWSCall.m in Sources */,
45855F381D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */,
B660F7681C29988E00687D6E /* CategorizingLogger.m in Sources */,
B660F7691C29988E00687D6E /* DecayingSampleEstimator.m in Sources */,
B660F76A1C29988E00687D6E /* EventWindow.m in Sources */,
B660F76B1C29988E00687D6E /* LoggingUtil.m in Sources */,
B660F76C1C29988E00687D6E /* AnonymousConditionLogger.m in Sources */,
45DF5DF31DDB843F00C936C7 /* CompareSafetyNumbersActivity.swift in Sources */,
456AC8341E3A775E00A3C7FC /* Weak.swift in Sources */,
B660F76D1C29988E00687D6E /* AnonymousOccurrenceLogger.m in Sources */,
B660F76E1C29988E00687D6E /* AnonymousValueLogger.m in Sources */,
B660F76F1C29988E00687D6E /* DiscardingLog.m in Sources */,
B660F7701C29988E00687D6E /* FLAnimatedImage.m in Sources */,
B660F7711C29988E00687D6E /* FLAnimatedImageView.m in Sources */,
B660F7721C29988E00687D6E /* AppStoreRating.m in Sources */,
@ -2381,53 +2128,34 @@
B660F7761C29988E00687D6E /* UIFont+OWS.m in Sources */,
B660F7771C29988E00687D6E /* UIImage+normalizeImage.m in Sources */,
954AEE6A1DF33E01002E5410 /* ContactsPickerTest.swift in Sources */,
B660F7781C29988E00687D6E /* ArrayUtil.m in Sources */,
B660F7791C29988E00687D6E /* CyclicalBuffer.m in Sources */,
B660F77A1C29988E00687D6E /* PriorityQueue.m in Sources */,
B660F77B1C29988E00687D6E /* Queue.m in Sources */,
B660F77C1C29988E00687D6E /* Conversions.m in Sources */,
B660F77D1C29988E00687D6E /* Crc32.m in Sources */,
B660F77E1C29988E00687D6E /* DataUtil.m in Sources */,
45666F581D9B2880008FE134 /* OWSScrubbingLogFormatterTest.m in Sources */,
B660F77F1C29988E00687D6E /* DateUtil.m in Sources */,
B660F7801C29988E00687D6E /* DictionaryUtil.m in Sources */,
B660F7811C29988E00687D6E /* FunctionalUtil.m in Sources */,
B660F7821C29988E00687D6E /* FutureUtil.m in Sources */,
B660F7831C29988E00687D6E /* NumberUtil.m in Sources */,
B660F7841C29988E00687D6E /* ObservableValue.m in Sources */,
B660F7851C29988E00687D6E /* Operation.m in Sources */,
B660F7861C29988E00687D6E /* AnonymousTerminator.m in Sources */,
B660F7871C29988E00687D6E /* StringUtil.m in Sources */,
45FBC5C91DF8575700E9B410 /* CallKitCallManager.swift in Sources */,
B660F7881C29988E00687D6E /* ThreadManager.m in Sources */,
B660F7891C29988E00687D6E /* TimeUtil.m in Sources */,
B660F78A1C29988E00687D6E /* UIUtil.m in Sources */,
B660F78B1C29988E00687D6E /* Zid.m in Sources */,
B660F78C1C29988E00687D6E /* UIDevice+TSHardwareVersion.m in Sources */,
456F6E211E2411B400FD2210 /* CallUIAdapter.swift in Sources */,
B660F6D81C29868000687D6E /* CryptoToolsTest.m in Sources */,
456F6E221E24132D00FD2210 /* PeerConnectionClient.swift in Sources */,
B660F6E01C29868000687D6E /* UtilTest.m in Sources */,
B660F6D61C29868000687D6E /* ConversionsTest.m in Sources */,
45F3AEB71DFDE7900080CE33 /* AvatarImageView.swift in Sources */,
B660F6DA1C29868000687D6E /* ExceptionsTest.m in Sources */,
45C9DEB91DF4E35A0065CA84 /* WebRTCCallMessageHandler.swift in Sources */,
B660F6DB1C29868000687D6E /* FunctionalUtilTest.m in Sources */,
452E3C8F1D935C77002A45B0 /* OWSConversationSettingsTableViewController.m in Sources */,
B660F6D71C29868000687D6E /* Crc32Test.m in Sources */,
B660F6D01C29868000687D6E /* DecayingSampleEstimatorTest.m in Sources */,
45E7A6A81E71CA7E00D44FB5 /* DisplayableTextFilterTest.swift in Sources */,
B660F6D11C29868000687D6E /* EventWindowTest.m in Sources */,
B660F6D51C29868000687D6E /* TestUtil.m in Sources */,
456F6E201E2411A000FD2210 /* CallService.swift in Sources */,
45E615171E8C59100018AD52 /* DisplayableTextFilter.swift in Sources */,
B660F6DF1C29868000687D6E /* QueueTest.m in Sources */,
B660F6BB1C29868000687D6E /* OWSContactsManagerTest.m in Sources */,
B660F6DD1C29868000687D6E /* ObservableTest.m in Sources */,
B660F6D21C29868000687D6E /* PushManagerTest.m in Sources */,
45C0DC1F1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */,
4505C2C01E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */,
B660F6D91C29868000687D6E /* CyclicalBufferTest.m in Sources */,
B660F6DC1C29868000687D6E /* FutureUtilTest.m in Sources */,
450873C81D9D867B006B54F2 /* OWSIncomingMessageCollectionViewCell.m in Sources */,
4505C2C61E64977D00CEBF41 /* ExperienceUpgradesPageViewController.swift in Sources */,
);

View File

@ -4,9 +4,7 @@
#import "AppDelegate.h"
#import "AppStoreRating.h"
#import "CategorizingLogger.h"
#import "CodeVerificationViewController.h"
#import "DataUtil.h"
#import "DebugLogger.h"
#import "Environment.h"
#import "NotificationsManager.h"
@ -102,13 +100,8 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
// XXX - careful when moving this. It must happen before we initialize TSStorageManager.
[self verifyDBKeysAvailableBeforeBackgroundLaunch];
// Initializing env logger
CategorizingLogger *logger = [CategorizingLogger categorizingLogger];
[logger addLoggingCallback:^(NSString *category, id details, NSUInteger index){
}];
// Setting up environment
[Environment setCurrent:[Release releaseEnvironmentWithLogging:logger]];
[Environment setCurrent:[Release releaseEnvironment]];
[UIUtil applySignalAppearence];
[[PushManager sharedManager] registerPushKitNotificationFuture];
@ -233,7 +226,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
DDLogError(@"%@ Failed to register for remote notifications with error %@", self.tag, error);
#ifdef DEBUG
DDLogWarn(@"%@ We're in debug mode. Faking success for remote registration with a fake push identifier", self.tag);
[PushManager.sharedManager.pushNotificationFutureSource trySetResult:[NSData dataWithLength:32]];
[PushManager.sharedManager.pushNotificationFutureSource trySetResult:[[NSMutableData dataWithLength:32] copy]];
#else
[PushManager.sharedManager.pushNotificationFutureSource trySetFailure:error];
#endif

View File

@ -1,44 +1,13 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
/// All dependencies on external libraries used for cryptography should be hidden behind CryptoTools methods.
/// That way, changing to a different library affects only one part of the system.
@interface CryptoTools : NSObject
/// Returns a secure random 16-bit unsigned integer.
+ (uint16_t)generateSecureRandomUInt16;
/// Returns a secure random 32-bit unsigned integer.
+ (uint32_t)generateSecureRandomUInt32;
/// Returns data composed of 'length' cryptographically unpredictable bytes sampled uniformly from [0, 256).
+ (NSData *)generateSecureRandomData:(NSUInteger)length;
/// Returns the token included as part of HTTP OTP authentication.
+ (NSString *)computeOtpWithPassword:(NSString *)password andCounter:(int64_t)counter;
@end
@interface NSData (CryptoTools)
- (NSData *)hashWithSha256;
- (NSData *)hmacWithSha1WithKey:(NSData *)key;
- (NSData *)hmacWithSha256WithKey:(NSData *)key;
- (NSData *)encryptWithAesInCipherFeedbackModeWithKey:(NSData *)key andIv:(NSData *)iv;
- (NSData *)decryptWithAesInCipherFeedbackModeWithKey:(NSData *)key andIv:(NSData *)iv;
- (NSData *)encryptWithAesInCipherBlockChainingModeWithPkcs7PaddingWithKey:(NSData *)key andIv:(NSData *)iv;
- (NSData *)decryptWithAesInCipherBlockChainingModeWithPkcs7PaddingWithKey:(NSData *)key andIv:(NSData *)iv;
- (NSData *)encryptWithAesInCounterModeWithKey:(NSData *)key andIv:(NSData *)iv;
- (NSData *)decryptWithAesInCounterModeWithKey:(NSData *)key andIv:(NSData *)iv;
/// Determines if two data vectors contain the same information.
/// Avoids short-circuiting or data-dependent branches, so that early returns can't be used to infer where the
/// difference is.
/// Returns early if data is of different length.
- (bool)isEqualToData_TimingSafe:(NSData *)other;
@end

View File

@ -4,11 +4,6 @@
#import "CryptoTools.h"
#import "Conversions.h"
#import "EvpMessageDigest.h"
#import "EvpSymetricUtil.h"
#import "Util.h"
@implementation CryptoTools
+ (NSData *)generateSecureRandomData:(NSUInteger)length {
@ -20,66 +15,4 @@
return [d copy];
}
+ (uint16_t)generateSecureRandomUInt16 {
return [[self generateSecureRandomData:sizeof(uint16_t)] bigEndianUInt16At:0];
}
+ (uint32_t)generateSecureRandomUInt32 {
return [[self generateSecureRandomData:sizeof(uint32_t)] bigEndianUInt32At:0];
}
+ (NSString *)computeOtpWithPassword:(NSString *)password andCounter:(int64_t)counter {
ows_require(password != nil);
NSData *d = [[@(counter) stringValue] encodedAsUtf8];
NSData *h = [d hmacWithSha1WithKey:password.encodedAsUtf8];
return h.encodedAsBase64;
}
@end
@implementation NSData (CryptoTools)
- (NSData *)hmacWithSha1WithKey:(NSData *)key {
return [EvpMessageDigest hmacUsingSha1Data:self withKey:key];
}
- (NSData *)hmacWithSha256WithKey:(NSData *)key {
return [EvpMessageDigest hmacUsingSha256Data:self withKey:key];
}
- (NSData *)encryptWithAesInCipherFeedbackModeWithKey:(NSData *)key andIv:(NSData *)iv {
return [EvpSymetricUtil encryptMessage:self usingAes128WithCfbAndKey:key andIv:iv];
}
- (NSData *)encryptWithAesInCipherBlockChainingModeWithPkcs7PaddingWithKey:(NSData *)key andIv:(NSData *)iv {
return [EvpSymetricUtil encryptMessage:self usingAes128WithCbcAndPaddingAndKey:key andIv:iv];
}
- (NSData *)encryptWithAesInCounterModeWithKey:(NSData *)key andIv:(NSData *)iv {
return [EvpSymetricUtil encryptMessage:self usingAes128InCounterModeAndKey:key andIv:iv];
}
- (NSData *)decryptWithAesInCipherFeedbackModeWithKey:(NSData *)key andIv:(NSData *)iv {
return [EvpSymetricUtil decryptMessage:self usingAes128WithCfbAndKey:key andIv:iv];
}
- (NSData *)decryptWithAesInCipherBlockChainingModeWithPkcs7PaddingWithKey:(NSData *)key andIv:(NSData *)iv {
return [EvpSymetricUtil decryptMessage:self usingAes128WithCbcAndPaddingAndKey:key andIv:iv];
}
- (NSData *)decryptWithAesInCounterModeWithKey:(NSData *)key andIv:(NSData *)iv {
return [EvpSymetricUtil decryptMessage:self usingAes128InCounterModeAndKey:key andIv:iv];
}
- (NSData *)hashWithSha256 {
return [EvpMessageDigest hashWithSha256:self];
}
- (bool)isEqualToData_TimingSafe:(NSData *)other {
if (other == nil)
return false;
NSUInteger n = self.length;
if (other.length != n)
return false;
bool equal = true;
for (NSUInteger i = 0; i < n; i++)
equal &= [self uint8At:i] == [other uint8At:i];
return equal;
}
@end

View File

@ -1,10 +0,0 @@
#import <Foundation/Foundation.h>
// Implements class level functions for Openssl's EVP_Digest Api
@interface EvpMessageDigest : NSObject
+ (NSData *)hashWithSha256:(NSData *)data;
+ (NSData *)hmacUsingSha1Data:(NSData *)data withKey:(NSData *)key;
+ (NSData *)hmacUsingSha256Data:(NSData *)data withKey:(NSData *)key;
@end

View File

@ -1,52 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "EvpMessageDigest.h"
#import <OpenSSL/evp.h>
#import <OpenSSL/hmac.h>
#import "EvpUtil.h"
#import "NumberUtil.h"
@implementation EvpMessageDigest
+ (NSData *)hash:(NSData *)data withDigest:(const EVP_MD *)digest {
NSUInteger expectedDigestLength = [NumberUtil assertConvertIntToNSUInteger:EVP_MD_size(digest)];
unsigned int digestLength = 0;
unsigned char digestBuffer[expectedDigestLength];
EVP_MD_CTX *ctx = EVP_MD_CTX_create();
ows_require(NULL != ctx);
@try {
RAISE_EXCEPTION_ON_FAILURE(EVP_DigestInit_ex(ctx, digest, NULL));
RAISE_EXCEPTION_ON_FAILURE(EVP_DigestUpdate(ctx, data.bytes, data.length));
RAISE_EXCEPTION_ON_FAILURE(EVP_DigestFinal_ex(ctx, digestBuffer, &digestLength));
} @finally {
EVP_MD_CTX_destroy(ctx);
}
ows_require(digestLength == expectedDigestLength);
return [NSData dataWithBytes:digestBuffer length:digestLength];
}
+ (NSData *)hmacWithData:(NSData *)data andKey:(NSData *)key andDigest:(const EVP_MD *)md {
NSUInteger digestLength = [NumberUtil assertConvertIntToNSUInteger:EVP_MD_size(md)];
unsigned char *digest = HMAC(
md, [key bytes], [NumberUtil assertConvertNSUIntegerToInt:key.length], [data bytes], data.length, NULL, NULL);
return [NSData dataWithBytes:digest length:digestLength];
}
+ (NSData *)hashWithSha256:(NSData *)data {
return [self hash:data withDigest:EVP_sha256()];
}
+ (NSData *)hmacUsingSha1Data:(NSData *)data withKey:(NSData *)key {
return [self hmacWithData:data andKey:key andDigest:EVP_sha1()];
}
+ (NSData *)hmacUsingSha256Data:(NSData *)data withKey:(NSData *)key {
return [self hmacWithData:data andKey:key andDigest:EVP_sha256()];
}
@end

View File

@ -1,16 +0,0 @@
#import <Foundation/Foundation.h>
#import <openssl/evp.h>
// Implements Symetric encryption methods using Openssl EVP Api. Raises Exceptions on failure.
@interface EvpSymetricUtil : NSObject
+ (NSData *)encryptMessage:(NSData *)message usingAes128WithCbcAndPaddingAndKey:(NSData *)key andIv:(NSData *)iv;
+ (NSData *)decryptMessage:(NSData *)message usingAes128WithCbcAndPaddingAndKey:(NSData *)key andIv:(NSData *)iv;
+ (NSData *)encryptMessage:(NSData *)message usingAes128WithCfbAndKey:(NSData *)key andIv:(NSData *)iv;
+ (NSData *)decryptMessage:(NSData *)message usingAes128WithCfbAndKey:(NSData *)key andIv:(NSData *)iv;
+ (NSData *)encryptMessage:(NSData *)message usingAes128InCounterModeAndKey:(NSData *)key andIv:(NSData *)iv;
+ (NSData *)decryptMessage:(NSData *)message usingAes128InCounterModeAndKey:(NSData *)key andIv:(NSData *)iv;
@end

View File

@ -1,112 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "EvpSymetricUtil.h"
#import "EvpUtil.h"
#import "NumberUtil.h"
@implementation EvpSymetricUtil
+ (NSData *)encryptMessage:(NSData *)message
usingCipher:(const EVP_CIPHER *)cipher
andKey:(NSData *)key
andIv:(NSData *)iv {
[self assertKey:key andIv:iv lengthsAgainstCipher:cipher];
int messageLength = [NumberUtil assertConvertNSUIntegerToInt:message.length];
int cipherBlockSize = EVP_CIPHER_block_size(cipher);
int cipherTextLength = 0;
int paddingLength = 0;
int bufferLength = (messageLength + cipherBlockSize - 1);
unsigned char cipherText[bufferLength];
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
if (!ctx) {
RAISE_EXCEPTION;
}
@try {
RAISE_EXCEPTION_ON_FAILURE(EVP_EncryptInit_ex(ctx, cipher, NULL, [key bytes], [iv bytes]))
RAISE_EXCEPTION_ON_FAILURE(
EVP_EncryptUpdate(ctx, cipherText, &cipherTextLength, [message bytes], messageLength))
RAISE_EXCEPTION_ON_FAILURE(EVP_EncryptFinal_ex(ctx, cipherText + cipherTextLength, &paddingLength))
cipherTextLength += paddingLength;
} @finally {
EVP_CIPHER_CTX_free(ctx);
}
ows_require(cipherTextLength <= bufferLength);
return [NSData dataWithBytes:cipherText length:[NumberUtil assertConvertIntToNSUInteger:cipherTextLength]];
}
+ (void)assertKey:(NSData *)key andIv:(NSData *)iv lengthsAgainstCipher:(const EVP_CIPHER *)cipher {
int cipherKeyLength = EVP_CIPHER_key_length(cipher);
int cipherIvLength = EVP_CIPHER_iv_length(cipher);
ows_require(key.length == [NumberUtil assertConvertIntToNSUInteger:cipherKeyLength]);
ows_require(iv.length == [NumberUtil assertConvertIntToNSUInteger:cipherIvLength]);
}
+ (NSData *)decryptMessage:(NSData *)cipherText
usingCipher:(const EVP_CIPHER *)cipher
andKey:(NSData *)key
andIv:(NSData *)iv {
[self assertKey:key andIv:iv lengthsAgainstCipher:cipher];
int cipherTextLength = [NumberUtil assertConvertNSUIntegerToInt:cipherText.length];
int cipherBlockSize = EVP_CIPHER_block_size(cipher);
int plainTextLength = 0;
int paddingLength = 0;
int bufferLength = (cipherTextLength + cipherBlockSize);
unsigned char plainText[bufferLength];
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
if (!ctx) {
RAISE_EXCEPTION;
}
@try {
RAISE_EXCEPTION_ON_FAILURE(EVP_DecryptInit_ex(ctx, cipher, NULL, [key bytes], [iv bytes]))
RAISE_EXCEPTION_ON_FAILURE(
EVP_DecryptUpdate(ctx, plainText, &plainTextLength, [cipherText bytes], cipherTextLength))
RAISE_EXCEPTION_ON_FAILURE(EVP_DecryptFinal_ex(ctx, plainText + plainTextLength, &paddingLength))
plainTextLength += paddingLength;
} @finally {
EVP_CIPHER_CTX_free(ctx);
}
ows_require(plainTextLength <= bufferLength);
return [NSData dataWithBytes:plainText length:[NumberUtil assertConvertIntToNSUInteger:plainTextLength]];
}
+ (NSData *)encryptMessage:(NSData *)message usingAes128WithCbcAndPaddingAndKey:(NSData *)key andIv:(NSData *)iv {
return [self encryptMessage:message usingCipher:EVP_aes_128_cbc() andKey:key andIv:iv];
}
+ (NSData *)decryptMessage:(NSData *)message usingAes128WithCbcAndPaddingAndKey:(NSData *)key andIv:(NSData *)iv {
return [self decryptMessage:message usingCipher:EVP_aes_128_cbc() andKey:key andIv:iv];
}
+ (NSData *)encryptMessage:(NSData *)message usingAes128WithCfbAndKey:(NSData *)key andIv:(NSData *)iv {
return [self encryptMessage:message usingCipher:EVP_aes_128_cfb128() andKey:key andIv:iv];
}
+ (NSData *)decryptMessage:(NSData *)message usingAes128WithCfbAndKey:(NSData *)key andIv:(NSData *)iv {
return [self decryptMessage:message usingCipher:EVP_aes_128_cfb128() andKey:key andIv:iv];
}
+ (NSData *)encryptMessage:(NSData *)message usingAes128InCounterModeAndKey:(NSData *)key andIv:(NSData *)iv {
return [self encryptMessage:message usingCipher:EVP_aes_128_ctr() andKey:key andIv:iv];
}
+ (NSData *)decryptMessage:(NSData *)message usingAes128InCounterModeAndKey:(NSData *)key andIv:(NSData *)iv {
return [self decryptMessage:message usingCipher:EVP_aes_128_ctr() andKey:key andIv:iv];
}
@end
;

View File

@ -1,7 +0,0 @@
#import <Foundation/Foundation.h>
#define RAISE_EXCEPTION [NSException raise:@"OPENSSL_Exception" format:@"Line:%d File:%s ", __LINE__, __FILE__]
#define RAISE_EXCEPTION_ON_FAILURE(X) \
if (1 != X) { \
RAISE_EXCEPTION; \
}

View File

@ -3,7 +3,6 @@
//
#import <Foundation/Foundation.h>
#import "Logging.h"
#import "PropertyListPreferences.h"
#import "TSGroupModel.h"
#import "TSStorageHeaders.h"
@ -32,13 +31,11 @@
@interface Environment : NSObject
- (instancetype)initWithLogging:(id<Logging>)logging
contactsManager:(OWSContactsManager *)contactsManager
contactsUpdater:(ContactsUpdater *)contactsUpdater
networkManager:(TSNetworkManager *)networkManager
messageSender:(OWSMessageSender *)messageSender;
- (instancetype)initWithContactsManager:(OWSContactsManager *)contactsManager
contactsUpdater:(ContactsUpdater *)contactsUpdater
networkManager:(TSNetworkManager *)networkManager
messageSender:(OWSMessageSender *)messageSender;
@property (nonatomic, readonly) id<Logging> logging;
@property (nonatomic, readonly) AccountManager *accountManager;
@property (nonatomic, readonly) OWSWebRTCCallMessageHandler *callMessageHandler;
@property (nonatomic, readonly) CallUIAdapter *callUIAdapter;
@ -57,7 +54,6 @@
+ (Environment *)getCurrent;
+ (void)setCurrent:(Environment *)curEnvironment;
+ (id<Logging>)logging;
+ (PropertyListPreferences *)preferences;

View File

@ -35,18 +35,16 @@ static Environment *environment = nil;
environment = curEnvironment;
}
- (instancetype)initWithLogging:(id<Logging>)logging
contactsManager:(OWSContactsManager *)contactsManager
contactsUpdater:(ContactsUpdater *)contactsUpdater
networkManager:(TSNetworkManager *)networkManager
messageSender:(OWSMessageSender *)messageSender
- (instancetype)initWithContactsManager:(OWSContactsManager *)contactsManager
contactsUpdater:(ContactsUpdater *)contactsUpdater
networkManager:(TSNetworkManager *)networkManager
messageSender:(OWSMessageSender *)messageSender
{
self = [super init];
if (!self) {
return self;
}
_logging = logging;
_contactsManager = contactsManager;
_contactsUpdater = contactsUpdater;
_networkManager = networkManager;
@ -116,15 +114,6 @@ static Environment *environment = nil;
return _outboundCallInitiator;
}
+ (id<Logging>)logging {
// Many tests create objects that rely on Environment only for logging.
// So we bypass the nil check in getCurrent and silently don't log during unit testing, instead of failing hard.
if (environment == nil)
return nil;
return Environment.getCurrent.logging;
}
- (NotificationsManager *)notificationsManager
{
@synchronized (self) {

View File

@ -8,9 +8,9 @@
@interface Release : NSObject
/// Connects to actual production infrastructure
+ (Environment *)releaseEnvironmentWithLogging:(id<Logging>)logging;
+ (Environment *)releaseEnvironment;
+ (Environment *)stagingEnvironmentWithLogging:(id<Logging>)logging;
+ (Environment *)stagingEnvironment;
/// Fake environment with no logging
+ (Environment *)unitTestEnvironment:(NSArray *)testingAndLegacyOptions;

View File

@ -3,7 +3,6 @@
//
#import "Release.h"
#import "DiscardingLog.h"
#import "NotificationsManager.h"
#import "OWSContactsManager.h"
#import <SignalServiceKit/ContactsUpdater.h>
@ -12,7 +11,8 @@
@implementation Release
+ (Environment *)releaseEnvironmentWithLogging:(id<Logging>)logging {
+ (Environment *)releaseEnvironment
{
TSNetworkManager *networkManager = [TSNetworkManager sharedManager];
OWSContactsManager *contactsManager = [OWSContactsManager new];
ContactsUpdater *contactsUpdater = [ContactsUpdater sharedUpdater];
@ -21,14 +21,15 @@
contactsManager:contactsManager
contactsUpdater:contactsUpdater];
return [[Environment alloc] initWithLogging:logging
contactsManager:contactsManager
contactsUpdater:contactsUpdater
networkManager:networkManager
messageSender:messageSender];
return [[Environment alloc] initWithContactsManager:contactsManager
contactsUpdater:contactsUpdater
networkManager:networkManager
messageSender:messageSender];
}
+ (Environment *)stagingEnvironmentWithLogging:(id<Logging>)logging {
// TODELETE
+ (Environment *)stagingEnvironment
{
TSNetworkManager *networkManager = [TSNetworkManager sharedManager];
OWSContactsManager *contactsManager = [OWSContactsManager new];
ContactsUpdater *contactsUpdater = [ContactsUpdater sharedUpdater];
@ -37,13 +38,13 @@
contactsManager:contactsManager
contactsUpdater:contactsUpdater];
return [[Environment alloc] initWithLogging:logging
contactsManager:contactsManager
contactsUpdater:contactsUpdater
networkManager:networkManager
messageSender:messageSender];
return [[Environment alloc] initWithContactsManager:contactsManager
contactsUpdater:contactsUpdater
networkManager:networkManager
messageSender:messageSender];
}
// TODELETE
+ (Environment *)unitTestEnvironment:(NSArray *)testingAndLegacyOptions {
TSNetworkManager *networkManager = [TSNetworkManager sharedManager];
OWSContactsManager *contactsManager = [OWSContactsManager new];
@ -53,11 +54,10 @@
contactsManager:contactsManager
contactsUpdater:contactsUpdater];
return [[Environment alloc] initWithLogging:[DiscardingLog discardingLog]
contactsManager:nil
contactsUpdater:contactsUpdater
networkManager:networkManager
messageSender:messageSender];
return [[Environment alloc] initWithContactsManager:nil
contactsUpdater:contactsUpdater
networkManager:networkManager
messageSender:messageSender];
}
@end

View File

@ -4,11 +4,9 @@
#import <Foundation/Foundation.h>
#import "PhoneNumber.h"
#import "Zid.h"
#define LOCAL_NUMBER_KEY @"Number"
#define PASSWORD_COUNTER_KEY @"PasswordCounter"
#define SAVED_PASSWORD_KEY @"Password"
#define SIGNALING_MAC_KEY @"Signaling Mac Key"
#define SIGNALING_CIPHER_KEY @"Signaling Cipher Key"
#define SIGNALING_EXTRA_KEY @"Signaling Extra Key"
@ -17,16 +15,11 @@
@interface SignalKeyingStorage : NSObject
+ (void)generateSignaling;
+ (void)generateServerAuthPassword;
#pragma mark Signaling Key
+ (int64_t)getAndIncrementOneTimeCounter;
#pragma mark Server Auth
+ (NSString *)serverAuthPassword;
#pragma mark Signaling
+ (NSData *)signalingMacKey;

View File

@ -11,16 +11,10 @@
#define SIGNALING_MAC_KEY_LENGTH 20
#define SIGNALING_CIPHER_KEY_LENGTH 16
#define SAVED_PASSWORD_LENGTH 18
#define SIGNALING_EXTRA_KEY_LENGTH 4
@implementation SignalKeyingStorage
+ (void)generateServerAuthPassword {
[self storeString:[[CryptoTools generateSecureRandomData:SAVED_PASSWORD_LENGTH] encodedAsBase64]
forKey:SAVED_PASSWORD_KEY];
}
+ (void)generateSignaling {
[self storeData:[CryptoTools generateSecureRandomData:SIGNALING_MAC_KEY_LENGTH] forKey:SIGNALING_MAC_KEY];
[self storeData:[CryptoTools generateSecureRandomData:SIGNALING_CIPHER_KEY_LENGTH] forKey:SIGNALING_CIPHER_KEY];
@ -47,10 +41,6 @@
return [self dataForKey:SIGNALING_EXTRA_KEY andVerifyLength:SIGNALING_EXTRA_KEY_LENGTH];
}
+ (NSString *)serverAuthPassword {
return [self stringForKey:SAVED_PASSWORD_KEY];
}
#pragma mark Keychain wrapper methods
+ (void)storeData:(NSData *)data forKey:(NSString *)key {

View File

@ -1,18 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Logging.h"
@interface CategorizingLogger : NSObject <Logging> {
@private
NSMutableArray *callbacks;
@private
NSMutableDictionary *indexDic;
}
+ (CategorizingLogger *)categorizingLogger;
- (void)addLoggingCallback:(void (^)(NSString *category, id details, NSUInteger index))callback;
@end

View File

@ -1,59 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "AnonymousConditionLogger.h"
#import "AnonymousOccurrenceLogger.h"
#import "AnonymousValueLogger.h"
#import "CategorizingLogger.h"
#import "LoggingUtil.h"
@implementation CategorizingLogger
+ (CategorizingLogger *)categorizingLogger {
CategorizingLogger *c = [CategorizingLogger new];
c->callbacks = [NSMutableArray array];
c->indexDic = [NSMutableDictionary dictionary];
return c;
}
- (void)addLoggingCallback:(void (^)(NSString *category, id details, NSUInteger index))callback {
[callbacks addObject:[callback copy]];
}
- (void)log:(NSString *)category details:(id)details {
NSNumber *index = indexDic[category];
if (index == nil) {
index = @(indexDic.count);
indexDic[category] = index;
}
NSUInteger x = [index unsignedIntegerValue];
for (void (^callback)(NSString *category, id details, NSUInteger index) in callbacks) {
callback(category, details, x);
}
}
- (id<ValueLogger>)getValueLoggerForValue:(id)valueIdentity from:(id)sender {
id<ValueLogger> r = [AnonymousValueLogger anonymousValueLogger:^(double value) {
[self log:[NSString stringWithFormat:@"Value %@ from %@", valueIdentity, sender] details:@(value)];
}];
return [LoggingUtil throttleValueLogger:r discardingAfterEventForDuration:0.5];
}
- (id<OccurrenceLogger>)getOccurrenceLoggerForSender:(id)sender withKey:(NSString *)key {
id<OccurrenceLogger> r = [AnonymousOccurrenceLogger anonymousOccurencyLoggerWithMarker:^(id details) {
[self log:[NSString stringWithFormat:@"Mark %@ from %@", key, sender] details:details];
}];
return [LoggingUtil throttleOccurrenceLogger:r discardingAfterEventForDuration:0.5];
}
- (id<ConditionLogger>)getConditionLoggerForSender:(id)sender {
return [AnonymousConditionLogger anonymousConditionLoggerWithLogNotice:^(NSString *text) {
[self log:[NSString stringWithFormat:@"Notice from %@", sender] details:text];
}
andLogWarning:^(NSString *text) {
[self log:[NSString stringWithFormat:@"Warning from %@", sender] details:text];
}
andLogError:^(NSString *text) {
[self log:[NSString stringWithFormat:@"Error from %@", sender] details:text];
}];
}
@end

View File

@ -1,26 +0,0 @@
#import <Foundation/Foundation.h>
/// A sample estimate based on an exponential weighting of observed samples, favoring the latest samples.
@interface DecayingSampleEstimator : NSObject {
@private
double estimate;
@private
double decayPerUnitSample;
}
+ (DecayingSampleEstimator *)decayingSampleEstimatorWithInitialEstimate:(double)initialEstimate
andDecayPerUnitSample:(double)decayPerUnitSample;
+ (DecayingSampleEstimator *)decayingSampleEstimatorWithInitialEstimate:(double)initialEstimate
andDecayFactor:(double)decayFactor
perNSamples:(double)decayPeriod;
/// Decays the current estimate towards the given sample value, assuming a unit weighting.
- (void)updateWithNextSample:(double)sampleValue;
/// Decays the current estimate towards the given sample value, with a given weighting.
- (void)updateWithNextSample:(double)sampleValue withSampleWeight:(double)weight;
- (double)currentEstimate;
- (double)decayRatePerUnitSample;
- (void)forceEstimateTo:(double)newEstimate;
@end

View File

@ -1,52 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "DecayingSampleEstimator.h"
@implementation DecayingSampleEstimator
+ (DecayingSampleEstimator *)decayingSampleEstimatorWithInitialEstimate:(double)initialEstimate
andDecayPerUnitSample:(double)decayPerUnitSample {
ows_require(decayPerUnitSample >= 0);
ows_require(decayPerUnitSample <= 1);
DecayingSampleEstimator *d = [DecayingSampleEstimator new];
d->estimate = initialEstimate;
d->decayPerUnitSample = decayPerUnitSample;
return d;
}
+ (DecayingSampleEstimator *)decayingSampleEstimatorWithInitialEstimate:(double)initialEstimate
andDecayFactor:(double)decayFactor
perNSamples:(double)decayPeriod {
ows_require(decayFactor >= 0);
ows_require(decayFactor <= 1);
ows_require(decayPeriod > 0);
double decayPerUnitSample = 1 - pow(1 - decayFactor, 1 / decayPeriod);
return [DecayingSampleEstimator decayingSampleEstimatorWithInitialEstimate:initialEstimate
andDecayPerUnitSample:decayPerUnitSample];
}
- (void)updateWithNextSample:(double)sampleValue {
estimate *= 1 - decayPerUnitSample;
estimate += sampleValue * decayPerUnitSample;
}
- (void)updateWithNextSample:(double)sampleValue withSampleWeight:(double)weight {
ows_require(weight >= 0);
if (weight == 0)
return;
double decayPerWeightedSample = 1 - pow(1 - decayPerUnitSample, weight);
estimate *= 1 - decayPerWeightedSample;
estimate += sampleValue * decayPerWeightedSample;
}
- (double)currentEstimate {
return estimate;
}
- (void)forceEstimateTo:(double)newEstimate {
estimate = newEstimate;
}
- (double)decayRatePerUnitSample {
return decayPerUnitSample;
}
@end

View File

@ -1,17 +0,0 @@
#import <Foundation/Foundation.h>
#import "PriorityQueue.h"
@interface EventWindow : NSObject {
@private
NSTimeInterval windowDuration;
@private
PriorityQueue *events;
@private
NSTimeInterval lastWindowEnding;
}
+ (EventWindow *)eventWindowWithWindowDuration:(NSTimeInterval)windowDuration;
- (void)addEventAtTime:(NSTimeInterval)eventTime;
- (NSUInteger)countAfterRemovingEventsBeforeWindowEndingAt:(NSTimeInterval)endOfWindowTime;
@end

View File

@ -1,35 +0,0 @@
#import "EventWindow.h"
@implementation EventWindow
+ (EventWindow *)eventWindowWithWindowDuration:(NSTimeInterval)windowDuration {
ows_require(windowDuration >= 0);
EventWindow *w = [EventWindow new];
w->windowDuration = windowDuration;
w->events = [PriorityQueue priorityQueueAscendingWithComparator:^NSComparisonResult(id obj1, id obj2) {
return [(NSNumber *)obj1 compare:(NSNumber *)obj2];
}];
w->lastWindowEnding = -INFINITY;
return w;
}
- (void)addEventAtTime:(NSTimeInterval)eventTime {
[events enqueue:@(eventTime)];
}
- (NSUInteger)countAfterRemovingEventsBeforeWindowEndingAt:(NSTimeInterval)endOfWindowTime {
// because values are removed, going backwards will give misleading results.
// checking for this case so callers don't get silent bad results
// includes a small leeway in case of non-monotonic time source or extended precision lose
requireState(endOfWindowTime >= lastWindowEnding - 0.03);
lastWindowEnding = endOfWindowTime;
NSTimeInterval startOfWindowTime = endOfWindowTime - windowDuration;
while (events.count > 0 && [events.peek doubleValue] < startOfWindowTime) {
[events dequeue];
}
return events.count;
}
@end

View File

@ -1,23 +0,0 @@
#import <Foundation/Foundation.h>
#import "DecayingSampleEstimator.h"
#import "Logging.h"
@interface LoggingUtil : NSObject
+ (id<ValueLogger>)throttleValueLogger:(id<ValueLogger>)valueLogger
discardingAfterEventForDuration:(NSTimeInterval)duration;
+ (id<OccurrenceLogger>)throttleOccurrenceLogger:(id<OccurrenceLogger>)occurrenceLogger
discardingAfterEventForDuration:(NSTimeInterval)duration;
+ (id<ValueLogger>)getAccumulatingValueLoggerTo:(id<Logging>)logging named:(id)valueIdentity from:(id)sender;
+ (id<ValueLogger>)getDifferenceValueLoggerTo:(id<Logging>)logging named:(id)valueIdentity from:(id)sender;
+ (id<ValueLogger>)getAveragingValueLoggerTo:(id<Logging>)logging named:(id)valueIdentity from:(id)sender;
+ (id<ValueLogger>)getValueEstimateLoggerTo:(id<Logging>)logging
named:(id)valueIdentity
from:(id)sender
withEstimator:(DecayingSampleEstimator *)estimator;
+ (id<ValueLogger>)getMagnitudeDecayingToZeroValueLoggerTo:(id<Logging>)logging
named:(id)valueIdentity
from:(id)sender
withDecayFactor:(double)decayFactorPerSample;
@end

View File

@ -1,94 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "AnonymousOccurrenceLogger.h"
#import "AnonymousValueLogger.h"
#import "LoggingUtil.h"
#import "TimeUtil.h"
@implementation LoggingUtil
+ (id<ValueLogger>)throttleValueLogger:(id<ValueLogger>)valueLogger
discardingAfterEventForDuration:(NSTimeInterval)duration {
__block NSTimeInterval t = [TimeUtil time] - duration;
return [AnonymousValueLogger anonymousValueLogger:^(double value) {
double t2 = [TimeUtil time];
if (t2 - duration < t)
return;
t = t2;
[valueLogger logValue:value];
}];
}
+ (id<OccurrenceLogger>)throttleOccurrenceLogger:(id<OccurrenceLogger>)occurrenceLogger
discardingAfterEventForDuration:(NSTimeInterval)duration {
__block NSTimeInterval t = [TimeUtil time] - duration;
return [AnonymousOccurrenceLogger anonymousOccurencyLoggerWithMarker:^(id details) {
double t2 = [TimeUtil time];
if (t2 - duration < t)
return;
t = t2;
[occurrenceLogger markOccurrence:details];
}];
}
+ (id<ValueLogger>)getAccumulatingValueLoggerTo:(id<Logging>)logging named:(id)valueIdentity from:(id)sender {
__block double total = 0.0;
id<ValueLogger> norm = [logging getValueLoggerForValue:valueIdentity from:sender];
return [AnonymousValueLogger anonymousValueLogger:^(double value) {
total += value;
[norm logValue:total];
}];
}
+ (id<ValueLogger>)getDifferenceValueLoggerTo:(id<Logging>)logging named:(id)valueIdentity from:(id)sender {
__block double previous = 0.0;
__block bool hasPrevious = false;
id<ValueLogger> norm = [logging getValueLoggerForValue:valueIdentity from:sender];
return [AnonymousValueLogger anonymousValueLogger:^(double value) {
double d = value - previous;
previous = value;
if (hasPrevious) {
[norm logValue:d];
}
hasPrevious = true;
}];
}
+ (id<ValueLogger>)getAveragingValueLoggerTo:(id<Logging>)logging named:(id)valueIdentity from:(id)sender {
__block double total = 0.0;
__block NSUInteger count = 0;
id<ValueLogger> norm = [logging getValueLoggerForValue:valueIdentity from:sender];
return [AnonymousValueLogger anonymousValueLogger:^(double value) {
total += value;
count += 1;
[norm logValue:total / count];
}];
}
+ (id<ValueLogger>)getValueEstimateLoggerTo:(id<Logging>)logging
named:(id)valueIdentity
from:(id)sender
withEstimator:(DecayingSampleEstimator *)estimator {
ows_require(estimator != nil);
id<ValueLogger> norm = [logging getValueLoggerForValue:valueIdentity from:sender];
return [AnonymousValueLogger anonymousValueLogger:^(double value) {
[estimator updateWithNextSample:value];
[norm logValue:estimator.currentEstimate];
}];
}
+ (id<ValueLogger>)getMagnitudeDecayingToZeroValueLoggerTo:(id<Logging>)logging
named:(id)valueIdentity
from:(id)sender
withDecayFactor:(double)decayFactorPerSample {
ows_require(decayFactorPerSample <= 1);
ows_require(decayFactorPerSample >= 0);
__block double decayingEstimate = 0.0;
id<ValueLogger> norm = [logging getValueLoggerForValue:valueIdentity from:sender];
return [AnonymousValueLogger anonymousValueLogger:^(double value) {
value = ABS(value);
decayingEstimate = MAX(value, decayingEstimate * decayFactorPerSample);
[norm logValue:decayingEstimate];
}];
}
@end

View File

@ -1,7 +0,0 @@
#import <Foundation/Foundation.h>
@protocol ConditionLogger <NSObject>
- (void)logNotice:(id)details;
- (void)logWarning:(id)details;
- (void)logError:(id)details;
@end

View File

@ -1,24 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "ConditionLogger.h"
#import "OccurrenceLogger.h"
#import "ValueLogger.h"
@protocol Logging <NSObject>
/// Note: the logger MUST NOT store a reference to the given sender. Calling this method, or storing its result, must
/// not create a reference cycle.
- (id<OccurrenceLogger>)getOccurrenceLoggerForSender:(id)sender withKey:(NSString *)key;
/// Note: the logger MUST NOT store a reference to the given sender. Calling this method, or storing its result, must
/// not create a reference cycle.
- (id<ConditionLogger>)getConditionLoggerForSender:(id)sender;
/// Note: the logger MUST NOT store a reference to the given sender. Calling this method, or storing its result, must
/// not create a reference cycle.
- (id<ValueLogger>)getValueLoggerForValue:(id)valueIdentity from:(id)sender;
@end

View File

@ -1,5 +0,0 @@
#import <Foundation/Foundation.h>
@protocol OccurrenceLogger <NSObject>
- (void)markOccurrence:(id)details;
@end

View File

@ -1,7 +0,0 @@
#import <Foundation/Foundation.h>
@protocol ValueLogger <NSObject>
- (void)logValue:(double)value;
@end

View File

@ -1,14 +0,0 @@
#import <Foundation/Foundation.h>
#import "ConditionLogger.h"
@interface AnonymousConditionLogger : NSObject <ConditionLogger>
@property (nonatomic, readonly, copy) void (^logNoticeBlock)(id details);
@property (nonatomic, readonly, copy) void (^logWarningBlock)(id details);
@property (nonatomic, readonly, copy) void (^logErrorBlock)(id details);
+ (AnonymousConditionLogger *)anonymousConditionLoggerWithLogNotice:(void (^)(id details))logNotice
andLogWarning:(void (^)(id details))logWarning
andLogError:(void (^)(id details))logError;
@end

View File

@ -1,33 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "AnonymousConditionLogger.h"
@implementation AnonymousConditionLogger
+ (AnonymousConditionLogger *)anonymousConditionLoggerWithLogNotice:(void (^)(id details))logNotice
andLogWarning:(void (^)(id details))logWarning
andLogError:(void (^)(id details))logError {
ows_require(logNotice != nil);
ows_require(logWarning != nil);
ows_require(logError != nil);
AnonymousConditionLogger *a = [AnonymousConditionLogger new];
a->_logErrorBlock = logError;
a->_logWarningBlock = logWarning;
a->_logNoticeBlock = logNotice;
return a;
}
- (void)logError:(id)details {
_logErrorBlock(details);
}
- (void)logWarning:(id)details {
_logWarningBlock(details);
}
- (void)logNotice:(id)details {
_logNoticeBlock(details);
}
@end

View File

@ -1,10 +0,0 @@
#import <Foundation/Foundation.h>
#import "OccurrenceLogger.h"
@interface AnonymousOccurrenceLogger : NSObject <OccurrenceLogger>
@property (readonly, nonatomic, copy) void (^marker)(id details);
+ (AnonymousOccurrenceLogger *)anonymousOccurencyLoggerWithMarker:(void (^)(id details))marker;
@end

View File

@ -1,20 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "AnonymousOccurrenceLogger.h"
@implementation AnonymousOccurrenceLogger
+ (AnonymousOccurrenceLogger *)anonymousOccurencyLoggerWithMarker:(void (^)(id details))marker {
ows_require(marker != nil);
AnonymousOccurrenceLogger *a = [AnonymousOccurrenceLogger new];
a->_marker = marker;
return a;
}
- (void)markOccurrence:(id)details {
_marker(details);
}
@end

View File

@ -1,10 +0,0 @@
#import <Foundation/Foundation.h>
#import "ValueLogger.h"
@interface AnonymousValueLogger : NSObject <ValueLogger>
@property (nonatomic, readonly, copy) void (^logValueBlock)(double value);
+ (AnonymousValueLogger *)anonymousValueLogger:(void (^)(double value))logValue;
@end

View File

@ -1,20 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "AnonymousValueLogger.h"
@implementation AnonymousValueLogger
+ (AnonymousValueLogger *)anonymousValueLogger:(void (^)(double value))logValue {
ows_require(logValue != nil);
AnonymousValueLogger *a = [AnonymousValueLogger new];
a->_logValueBlock = logValue;
return a;
}
- (void)logValue:(double)value {
_logValueBlock(value);
}
@end

View File

@ -1,11 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "ConditionLogger.h"
#import "Logging.h"
@interface DiscardingLog : NSObject <Logging, OccurrenceLogger, ConditionLogger, ValueLogger>
+ (DiscardingLog *)discardingLog;
@end

View File

@ -1,34 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "DiscardingLog.h"
@implementation DiscardingLog
+ (DiscardingLog *)discardingLog {
return [DiscardingLog new];
}
- (id<OccurrenceLogger>)getOccurrenceLoggerForSender:(id)sender withKey:(NSString *)key {
return self;
}
- (id<ConditionLogger>)getConditionLoggerForSender:(id)sender {
return self;
}
- (id<ValueLogger>)getValueLoggerForValue:(id)valueIdentity from:(id)sender {
return self;
}
- (void)logValue:(double)value {
}
- (void)markOccurrence:(id)details {
}
- (void)logError:(NSString *)text {
}
- (void)logNotice:(NSString *)text {
}
- (void)logWarning:(NSString *)text {
}
@end

View File

@ -1,7 +0,0 @@
#import <Foundation/Foundation.h>
@interface NSArray (Util)
- (NSData *)ows_toUint8Data;
- (NSData *)ows_concatDatas;
- (NSArray *)ows_concatArrays;
@end

View File

@ -1,41 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "ArrayUtil.h"
@implementation NSArray (Util)
- (NSData *)ows_toUint8Data {
NSUInteger n = self.count;
uint8_t x[n];
for (NSUInteger i = 0; i < n; i++) {
x[i] = [(NSNumber *)self[i] unsignedCharValue];
}
return [NSData dataWithBytes:x length:n];
}
- (NSData *)ows_concatDatas {
NSUInteger t = 0;
for (id d in self) {
ows_require([d isKindOfClass:NSData.class]);
t += [(NSData *)d length];
}
NSMutableData *result = [NSMutableData dataWithLength:t];
uint8_t *dst = [result mutableBytes];
for (NSData *d in self) {
memcpy(dst, [d bytes], d.length);
dst += d.length;
}
return result;
}
- (NSArray *)ows_concatArrays {
NSMutableArray *r = [NSMutableArray array];
for (id e in self) {
ows_require([e isKindOfClass:NSArray.class]);
[r addObjectsFromArray:e];
}
return r;
}
@end

View File

@ -1,15 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <CoreFoundation/CFSocket.h>
#import <Foundation/Foundation.h>
#import "CryptoTools.h"
@interface NSData (Conversions)
- (uint16_t)bigEndianUInt16At:(NSUInteger)offset;
- (uint32_t)bigEndianUInt32At:(NSUInteger)offset;
+ (NSData *)dataWithBigEndianBytesOfUInt16:(uint16_t)value;
+ (NSData *)dataWithBigEndianBytesOfUInt32:(uint32_t)value;
+ (NSData *)switchEndiannessOfData:(NSData *)data;
@end

View File

@ -1,40 +0,0 @@
#import "Conversions.h"
#import "Util.h"
@implementation NSData (Conversions)
- (uint16_t)bigEndianUInt16At:(NSUInteger)offset {
ows_require(offset <= self.length - sizeof(uint16_t));
return (uint16_t)[self uint8At:1 + offset] | (uint16_t)((uint16_t)[self uint8At:0 + offset] << 8);
}
- (uint32_t)bigEndianUInt32At:(NSUInteger)offset {
ows_require(offset <= self.length - sizeof(uint32_t));
return ((uint32_t)[self uint8At:3 + offset] << 0) | ((uint32_t)[self uint8At:2 + offset] << 8) |
((uint32_t)[self uint8At:1 + offset] << 16) | ((uint32_t)[self uint8At:0 + offset] << 24);
}
+ (NSData *)dataWithBigEndianBytesOfUInt16:(uint16_t)value {
uint8_t d[sizeof(uint16_t)];
d[1] = (uint8_t)((value >> 0) & 0xFF);
d[0] = (uint8_t)((value >> 8) & 0xFF);
return [NSData dataWithBytes:d length:sizeof(uint16_t)];
}
+ (NSData *)dataWithBigEndianBytesOfUInt32:(uint32_t)value {
uint8_t d[sizeof(uint32_t)];
d[3] = (uint8_t)((value >> 0) & 0xFF);
d[2] = (uint8_t)((value >> 8) & 0xFF);
d[1] = (uint8_t)((value >> 16) & 0xFF);
d[0] = (uint8_t)((value >> 24) & 0xFF);
return [NSData dataWithBytes:d length:sizeof(uint32_t)];
}
+ (NSData *)switchEndiannessOfData:(NSData *)data {
const void *bytes = [data bytes];
NSMutableData *switchedEndianData = [NSMutableData new];
for (NSUInteger i = data.length; i > 0; --i) {
uint8_t byte = *(((uint8_t *)(bytes)) + ((i - 1) * sizeof(uint8_t)));
[switchedEndianData appendData:[NSData dataWithBytes:&byte length:sizeof(byte)]];
}
return switchedEndianData;
}
@end

View File

@ -1,7 +0,0 @@
#import <Foundation/Foundation.h>
@interface NSData (CRC)
- (uint32_t)crc32;
@end

View File

@ -1,44 +0,0 @@
#import "Crc32.h"
#define DEFAULT_POLYNOMIAL 0xEDB88320L
#define DEFAULT_SEED 0xFFFFFFFFL
void generateCRC32Table(uint32_t *pTable, uint32_t poly);
@implementation NSData (CRC)
void generateCRC32Table(uint32_t *pTable, uint32_t poly) {
for (uint32_t i = 0; i <= 255; i++) {
uint32_t crc = i;
for (uint32_t j = 8; j > 0; j--) {
if ((crc & 1) == 1)
crc = (crc >> 1) ^ poly;
else
crc >>= 1;
}
pTable[i] = crc;
}
}
- (uint32_t)crc32 {
return [self crc32WithSeed:DEFAULT_SEED usingPolynomial:DEFAULT_POLYNOMIAL];
}
- (uint32_t)crc32WithSeed:(uint32_t)seed usingPolynomial:(uint32_t)poly {
uint32_t *pTable = malloc(sizeof(uint32_t) * 256);
generateCRC32Table(pTable, poly);
uint32_t crc = seed;
uint8_t *pBytes = (uint8_t *)[self bytes];
NSUInteger length = self.length;
while (length--) {
crc = (crc >> 8) ^ pTable[(crc & 0xFF) ^ *pBytes++];
}
free(pTable);
return crc ^ 0xFFFFFFFFL;
}
@end

View File

@ -1,77 +0,0 @@
#import <Foundation/Foundation.h>
@interface NSData (Util)
- (NSString *)encodedAsHexString;
- (const void *)bytesNotNull;
+ (NSData *)dataWithLength:(NSUInteger)length;
+ (NSData *)dataWithSingleByte:(uint8_t)value;
/// Decodes the data as a utf-8 string.
- (NSString *)decodedAsUtf8;
/// Decodes the data as an ascii string.
/// Throws when the data contains non-ascii character data (bytes larger than 127).
- (NSString *)decodedAsAscii;
/// Decodes the data as an ascii string.
/// Replaces any bad or non-printable characters with dots.
- (NSString *)decodedAsAsciiReplacingErrorsWithDots;
/// Finds the first index where the given sub data is present.
/// Returns nil if there is no such index.
- (NSNumber *)tryFindIndexOf:(NSData *)subData;
- (NSData *)skip:(NSUInteger)offset;
- (NSData *)take:(NSUInteger)takeCount;
- (NSData *)skipLast:(NSUInteger)skipLastCount;
- (NSData *)takeLast:(NSUInteger)takeLastCount;
/// Returns an NSData referencing a subrange of another NSData.
/// Modifying the original NSData will modify the result.
/// If the original is dealloced before the result, bad things happen to you.
- (NSData *)subdataVolatileWithRange:(NSRange)range;
/// Returns an NSData referencing the end of another NSData.
/// Modifying the original NSData will modify the result.
/// If the original is dealloced before the result, bad things happen to you.
- (NSData *)skipVolatile:(NSUInteger)offset;
/// Returns an NSData referencing the start of another NSData.
/// Modifying the original NSData will modify the result.
/// If the original is dealloced before the result, bad things happen to you.
- (NSData *)takeVolatile:(NSUInteger)takeCount;
/// Returns an NSData referencing the start of another NSData.
/// Modifying the original NSData will modify the result.
/// If the original is dealloced before the result, bad things happen to you.
- (NSData *)skipLastVolatile:(NSUInteger)skipLastCount;
/// Returns an NSData referencing the end of another NSData.
/// Modifying the original NSData will modify the result.
/// If the original is dealloced before the result, bad things happen to you.
- (NSData *)takeLastVolatile:(NSUInteger)takeLastCount;
- (uint8_t)uint8At:(NSUInteger)offset;
- (uint8_t)highUint4AtByteOffset:(NSUInteger)offset;
- (uint8_t)lowUint4AtByteOffset:(NSUInteger)offset;
- (NSString *)encodedAsBase64;
@end
@interface NSMutableData (Util)
- (void)replaceBytesStartingAt:(NSUInteger)offset withData:(NSData *)data;
- (void)setUint8At:(NSUInteger)offset to:(uint8_t)newValue;
@end

View File

@ -1,202 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "DataUtil.h"
@implementation NSData (Util)
- (const void *)bytesNotNull {
// note: this storage location is static, not auto, so its lifetime does not end
// (also, by virtue of being const, there are no threading/entrancy issues)
static const int SafeNonNullPointerToStaticStorageLocation[1];
if (self.length == 0) {
return SafeNonNullPointerToStaticStorageLocation;
} else {
ows_require([self bytes] != nil);
return [self bytes];
}
}
+ (NSData *)dataWithLength:(NSUInteger)length {
return [NSMutableData dataWithLength:length];
}
+ (NSData *)dataWithSingleByte:(uint8_t)value {
return [NSData dataWithBytes:&value length:sizeof(value)];
}
- (NSNumber *)tryFindIndexOf:(NSData *)subData {
ows_require(subData != nil);
if (subData.length > self.length)
return nil;
NSUInteger subDataLength = subData.length;
NSUInteger excessLength = self.length - subDataLength;
const uint8_t *selfBytes = [self bytes];
const uint8_t *subDataBytes = [subData bytes];
for (NSUInteger i = 0; i <= excessLength; i++) {
if (memcmp(selfBytes + i, subDataBytes, subDataLength) == 0) {
return @(i);
}
}
return nil;
}
- (NSString *)encodedAsHexString {
if (![self bytes])
return @"";
NSMutableString *result = [NSMutableString string];
for (NSUInteger i = 0; i < self.length; ++i)
[result appendString:[NSString stringWithFormat:@"%02x", [self uint8At:i]]];
return result;
}
- (NSString *)decodedAsUtf8 {
// workaround for empty data having nil bytes
if (self.length == 0)
return @"";
[NSString stringWithUTF8String:[self bytes]];
NSString *result = [[NSString alloc] initWithData:self encoding:NSUTF8StringEncoding];
checkOperationDescribe(result != nil, @"Invalid UTF8 data.");
return result;
}
- (NSString *)decodedAsAscii {
// workaround for empty data having nil bytes
if (self.length == 0)
return @"";
// workaround for initWithData not enforcing the fact that NSASCIIStringEncoding means strict 7-bit
for (NSUInteger i = 0; i < self.length; i++) {
checkOperationDescribe(([self uint8At:i] & 0x80) == 0, @"Invalid ascii data.");
}
NSString *result = [[NSString alloc] initWithData:self encoding:NSASCIIStringEncoding];
checkOperationDescribe(result != nil, @"Invalid ascii data.");
return result;
}
- (NSString *)decodedAsAsciiReplacingErrorsWithDots {
const int MinPrintableChar = ' ';
const int MaxPrintableChar = '~';
NSMutableData *d = [NSMutableData dataWithLength:self.length];
for (NSUInteger i = 0; i < self.length; i++) {
uint8_t v = [self uint8At:i];
if (v < MinPrintableChar || v > MaxPrintableChar)
v = '.';
[d setUint8At:i to:v];
}
return [d decodedAsAscii];
}
- (NSData *)skip:(NSUInteger)offset {
ows_require(offset <= self.length);
return [self subdataWithRange:NSMakeRange(offset, self.length - offset)];
}
- (NSData *)take:(NSUInteger)takeCount {
ows_require(takeCount <= self.length);
return [self subdataWithRange:NSMakeRange(0, takeCount)];
}
- (NSData *)skipLast:(NSUInteger)skipLastCount {
ows_require(skipLastCount <= self.length);
return [self subdataWithRange:NSMakeRange(0, self.length - skipLastCount)];
}
- (NSData *)takeLast:(NSUInteger)takeLastCount {
ows_require(takeLastCount <= self.length);
return [self subdataWithRange:NSMakeRange(self.length - takeLastCount, takeLastCount)];
}
- (NSData *)subdataVolatileWithRange:(NSRange)range {
NSUInteger length = self.length;
ows_require(range.location <= length);
ows_require(range.length <= length);
ows_require(range.location + range.length <= length);
return [NSData dataWithBytesNoCopy:(uint8_t *)[self bytes] + range.location length:range.length freeWhenDone:NO];
}
- (NSData *)skipVolatile:(NSUInteger)offset {
ows_require(offset <= self.length);
return [self subdataVolatileWithRange:NSMakeRange(offset, self.length - offset)];
}
- (NSData *)takeVolatile:(NSUInteger)takeCount {
ows_require(takeCount <= self.length);
return [self subdataVolatileWithRange:NSMakeRange(0, takeCount)];
}
- (NSData *)skipLastVolatile:(NSUInteger)skipLastCount {
ows_require(skipLastCount <= self.length);
return [self subdataVolatileWithRange:NSMakeRange(0, self.length - skipLastCount)];
}
- (NSData *)takeLastVolatile:(NSUInteger)takeLastCount {
ows_require(takeLastCount <= self.length);
return [self subdataVolatileWithRange:NSMakeRange(self.length - takeLastCount, takeLastCount)];
}
- (uint8_t)highUint4AtByteOffset:(NSUInteger)offset {
return [self uint8At:offset] >> 4;
}
- (uint8_t)lowUint4AtByteOffset:(NSUInteger)offset {
return [self uint8At:offset] & 0xF;
}
- (uint8_t)uint8At:(NSUInteger)offset {
ows_require(offset < self.length);
return ((const uint8_t *)[self bytes])[offset];
}
- (const uint8_t *)constPtrToUint8At:(NSUInteger)offset {
return ((uint8_t *)[self bytes]) + offset;
}
- (NSString *)encodedAsBase64 {
const NSUInteger BitsPerBase64Word = 6;
const NSUInteger BitsPerByte = 8;
const uint8_t Base64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
NSUInteger byteCount = self.length;
NSUInteger bitCount = byteCount * BitsPerByte;
NSUInteger base64WordCount = bitCount / BitsPerBase64Word;
if (base64WordCount * BitsPerBase64Word < bitCount)
base64WordCount += 1;
// base 256 to to base 2
bool bits[bitCount];
for (NSUInteger i = 0; i < byteCount; i++) {
for (NSUInteger j = 0; j < BitsPerByte; j++) {
bits[i * BitsPerByte + BitsPerByte - 1 - j] = (([self uint8At:i] >> j) & 1) != 0;
}
}
// base 2 to base 64
uint8_t base64Words[base64WordCount];
for (NSUInteger i = 0; i < base64WordCount; i++) {
base64Words[i] = 0;
for (NSUInteger j = 0; j < BitsPerBase64Word; j++) {
NSUInteger offset = i * BitsPerBase64Word + BitsPerBase64Word - 1 - j;
if (offset >= bitCount)
continue; // default to 0
if (bits[offset])
base64Words[i] |= 1 << j;
}
}
// base 64 to ASCII data
NSUInteger paddingCount = bitCount % 3;
NSMutableData *asciiData = [NSMutableData dataWithLength:base64WordCount + paddingCount];
for (NSUInteger i = 0; i < base64WordCount; i++) {
[asciiData setUint8At:i to:Base64Chars[base64Words[i]]];
}
for (NSUInteger i = 0; i < paddingCount; i++) {
[asciiData setUint8At:i + base64WordCount to:'='];
}
return [asciiData decodedAsAscii];
}
@end
@implementation NSMutableData (Util)
- (void)setUint8At:(NSUInteger)offset to:(uint8_t)newValue {
ows_require(offset < self.length);
((uint8_t *)[self mutableBytes])[offset] = newValue;
}
- (void)replaceBytesStartingAt:(NSUInteger)offset withData:(NSData *)data {
ows_require(data != nil);
ows_require(offset + data.length <= self.length);
[self replaceBytesInRange:NSMakeRange(offset, data.length) withBytes:[data bytes]];
}
@end

View File

@ -1,7 +0,0 @@
#import <Foundation/Foundation.h>
@interface NSDictionary (Util)
- (NSString *)encodedAsJson;
@end

View File

@ -1,17 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "DataUtil.h"
#import "DictionaryUtil.h"
@implementation NSDictionary (Util)
- (NSString *)encodedAsJson {
NSError *jsonSerializeError = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:self options:0 error:&jsonSerializeError];
checkOperation(jsonSerializeError == nil);
return [data decodedAsUtf8];
}
@end

View File

@ -1,63 +0,0 @@
#import <Foundation/Foundation.h>
#import "CollapsingFutures.h"
#import "Terminable.h"
@interface TOCCancelToken (FutureUtil)
- (void)whenCancelledTerminate:(id<Terminable>)terminable;
@end
@interface TOCFuture (FutureUtil)
/*!
* Wraps an asynchronous operation in a try-catch block, so it returns a failed future instead of propagating an
* exception.
*/
+ (TOCUntilOperation)operationTry:(TOCUntilOperation)operation;
/*!
* Returns a future that completes after the receiving future completes, but replaces its result if it didn't fail.
*/
- (TOCFuture *)thenValue:(id)value;
/*!
* A variant of `-finally` that wraps a try-catch statement around the continuation.
*
* @discussion Registers a continuation to run when the receiving future completes with a result or fails.
* Exposes the result of the continuation as a future.
* If the continuation throwns an exception, it is caught and the returned future will fail with the caught exception as
* its failure.
*/
- (TOCFuture *)finallyTry:(TOCFutureFinallyContinuation)callback;
/*!
* A variant of `-then` that wraps a try-catch statement around the continuation.
*
* @discussion Registers a continuation to run when the receiving future completes with a result.
* Exposes the result of the continuation as a future.
* If the receiving future fails, the returned future is given the same failure and the continuation is not run.
* If the continuation throwns an exception, it is caught and the returned future will fail with the caught exception as
* its failure.
*/
- (TOCFuture *)thenTry:(TOCFutureThenContinuation)projection;
/*!
* A variant of `-catch` that wraps a try-catch statement around the continuation.
*
* @discussion Registers a continuation to run when the receiving future fails.
* Exposes the result of the continuation as a future.
* If the receiving future completes with a result, the returned future is given the same result and the continuation is
* not run.
* If the continuation throwns an exception, it is caught and the returned future will fail with the caught exception as
* its failure.
*/
- (TOCFuture *)catchTry:(TOCFutureCatchContinuation)catcher;
+ (TOCFuture *)retry:(TOCUntilOperation)operation
upToNTimes:(NSUInteger)maxTryCount
withBaseTimeout:(NSTimeInterval)baseTimeout
andRetryFactor:(NSTimeInterval)timeoutRetryFactor
untilCancelled:(TOCCancelToken *)untilCancelledToken;
@end

View File

@ -1,104 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "FutureUtil.h"
@implementation TOCCancelToken (FutureUtil)
- (void)whenCancelledTerminate:(id<Terminable>)terminable {
ows_require(terminable != nil);
[self whenCancelledDo:^{
[terminable terminate];
}];
}
@end
@implementation TOCFuture (FutureUtil)
+ (TOCUntilOperation)operationTry:(TOCUntilOperation)operation {
ows_require(operation != nil);
return ^(TOCCancelToken *until) {
@try {
return operation(until);
} @catch (id ex) {
return [TOCFuture futureWithFailure:ex];
}
};
}
- (TOCFuture *)thenValue:(id)value {
return [self then:^(id _) {
return value;
}];
}
- (TOCFuture *)finallyTry:(TOCFutureFinallyContinuation)completionContinuation {
ows_require(completionContinuation != nil);
return [self finally:^id(TOCFuture *completed) {
@try {
return completionContinuation(completed);
} @catch (id ex) {
return [TOCFuture futureWithFailure:ex];
}
}];
}
- (TOCFuture *)thenTry:(TOCFutureThenContinuation)resultContinuation {
ows_require(resultContinuation != nil);
return [self then:^id(id result) {
@try {
return resultContinuation(result);
} @catch (id ex) {
return [TOCFuture futureWithFailure:ex];
}
}];
}
- (TOCFuture *)catchTry:(TOCFutureCatchContinuation)failureContinuation {
ows_require(failureContinuation != nil);
return [self catch:^id(id failure) {
@try {
return failureContinuation(failure);
} @catch (id ex) {
return [TOCFuture futureWithFailure:ex];
}
}];
}
+ (TOCFuture *)retry:(TOCUntilOperation)operation
upToNTimes:(NSUInteger)maxTryCount
withBaseTimeout:(NSTimeInterval)baseTimeout
andRetryFactor:(NSTimeInterval)timeoutRetryFactor
untilCancelled:(TOCCancelToken *)untilCancelledToken {
ows_require(operation != nil);
ows_require(maxTryCount >= 0);
ows_require(baseTimeout >= 0);
ows_require(timeoutRetryFactor >= 0);
if (maxTryCount == 0)
return TOCFuture.futureWithTimeoutFailure;
TOCFuture *futureResult =
[TOCFuture futureFromUntilOperation:operation withOperationTimeout:baseTimeout until:untilCancelledToken];
return [futureResult catchTry:^(id error) {
bool operationCancelled = untilCancelledToken.isAlreadyCancelled;
bool operationDidNotTimeout = !futureResult.hasFailedWithTimeout;
if (operationCancelled || operationDidNotTimeout) {
return [TOCFuture futureWithFailure:error];
}
return [self retry:operation
upToNTimes:maxTryCount - 1
withBaseTimeout:baseTimeout * timeoutRetryFactor
andRetryFactor:timeoutRetryFactor
untilCancelled:untilCancelledToken];
}];
}
@end

View File

@ -1,7 +1,8 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "ArrayUtil.h"
#import "DataUtil.h"
#import "DictionaryUtil.h"
#import "StringUtil.h"
@interface NumberUtil : NSObject

View File

@ -1,3 +1,7 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "Environment.h"
#import "ObservableValue.h"
#import "Util.h"
@ -61,8 +65,7 @@
@try {
action();
} @catch (id ex) {
[[Environment.logging getConditionLoggerForSender:self]
logError:@"A queued action failed and may have stalled an ObservableValue."];
DDLogError(@"A queued action failed and may have stalled an ObservableValue.");
@synchronized(self) {
isRunningActions = false;
}

View File

@ -1,7 +1,8 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "ArrayUtil.h"
#import "DataUtil.h"
#import "DictionaryUtil.h"
#import "StringUtil.h"
typedef void (^Action)(void);

View File

@ -2,7 +2,6 @@
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "DataUtil.h"
#import "NumberUtil.h"
#import "StringUtil.h"
@ -21,20 +20,6 @@
}
return [NSData dataWithBytes:result length:sizeof(result)];
}
- (NSData *)decodedAsSpaceSeparatedHexString {
NSArray *hexComponents = [self componentsSeparatedByString:@" "];
NSMutableData *result = [NSMutableData new];
for (NSString *component in hexComponents) {
unsigned int r;
NSScanner *scanner = [NSScanner scannerWithString:component];
checkOperation([scanner scanHexInt:&r]);
checkOperation(r < 256);
[result appendData:[NSData dataWithSingleByte:(uint8_t)r]];
}
return result;
}
- (NSData *)encodedAsUtf8 {
NSData *result = [self dataUsingEncoding:NSUTF8StringEncoding];
checkOperationDescribe(result != nil, @"Not a UTF8 string.");
@ -84,62 +69,6 @@
checkOperationDescribe([parsedJson isKindOfClass:NSDictionary.class], @"Unexpected json data");
return parsedJson;
}
- (NSData *)decodedAsBase64Data {
const NSUInteger BitsPerBase64Word = 6;
const NSUInteger BitsPerByte = 8;
const uint8_t Base64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
uint8_t CharToValueMap[256];
for (NSUInteger i = 0; i < 256; i++) {
CharToValueMap[i] = 255;
}
for (uint8_t i = 0; i < 64; i++) {
CharToValueMap[Base64Chars[i]] = i;
}
// Determine amount of information (based on length and padding)
NSUInteger paddingCount = 0;
while (paddingCount < 2 && paddingCount < self.length - 1 &&
[self characterAtIndex:self.length - paddingCount - 1] == '=') {
paddingCount += 1;
}
NSUInteger base64WordCount = self.length - paddingCount;
NSUInteger bitCount = self.length * BitsPerBase64Word - paddingCount * BitsPerByte;
NSUInteger byteCount = bitCount / BitsPerByte;
checkOperation(bitCount % BitsPerByte == 0);
// ASCII to base 64
NSData *asciiData = self.encodedAsAscii;
uint8_t base64Words[base64WordCount];
for (NSUInteger i = 0; i < base64WordCount; i++) {
base64Words[i] = CharToValueMap[[asciiData uint8At:i]];
ows_require(base64Words[i] < 64);
}
// base 64 to base 2
bool bits[bitCount];
for (NSUInteger i = 0; i < base64WordCount; i++) {
for (NSUInteger j = 0; j < BitsPerBase64Word; j++) {
NSUInteger k = (i + 1) * BitsPerBase64Word - 1 - j;
if (k >= bitCount)
continue; // may occur due to padding
bits[k] = ((base64Words[i] >> j) & 1) != 0;
}
}
// base 2 to base 256
uint8_t bytes[byteCount];
for (NSUInteger i = 0; i < byteCount; i++) {
bytes[i] = 0;
for (NSUInteger j = 0; j < BitsPerByte; j++) {
NSUInteger k = (i + 1) * BitsPerByte - 1 - j;
if (bits[k])
bytes[i] |= 1 << j;
}
}
return [NSData dataWithBytes:bytes length:sizeof(bytes)];
}
- (NSNumber *)tryParseAsDecimalNumber {
NSNumberFormatter *formatter = [NSNumberFormatter new];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];

View File

@ -1,52 +0,0 @@
#import <Foundation/Foundation.h>
@interface RunningThreadRunLoopPair : NSObject
@property (nonatomic, readonly) NSThread *thread;
@property (nonatomic, readonly) NSRunLoop *runLoop;
+ (RunningThreadRunLoopPair *)startNewWithThreadName:(NSString *)name;
- (void)terminate;
@end
/**
*
* The thread manager is responsible for starting and exposing the low/normal/high latency threads.
*
* Low latency:
* - Includes: Audio encoding/decoding, communicating audio data, advancing zrtp handshake, etc.
* - Operations on this thread should complete at human-interaction speeds (<30ms) and avoid swamping.
* - If an operation must be low latency but takes too long, split it into parts that can be interleaved.
*
* Normal latency:
* - Includes: Registration
* - Operations on this thread should complete at human-reaction speeds (<250ms).
*
* High latency:
* - Includes: DNS CNAME lookup (due to gethostbyname blocking and being non-reentrant and non-threadsafe)
* - Operations on this thread should complete at human-patience speeds (<10s).
*
*/
@interface ThreadManager : NSObject {
@private
RunningThreadRunLoopPair *low;
@private
RunningThreadRunLoopPair *normal;
@private
RunningThreadRunLoopPair *high;
}
+ (NSThread *)lowLatencyThread;
+ (NSRunLoop *)lowLatencyThreadRunLoop;
+ (NSThread *)normalLatencyThread;
+ (NSRunLoop *)normalLatencyThreadRunLoop;
+ (NSThread *)highLatencyThread;
+ (NSRunLoop *)highLatencyThreadRunLoop;
+ (void)terminate;
@end

View File

@ -1,88 +0,0 @@
#import "ThreadManager.h"
#import "Util.h"
#define LOW_THREAD_NAME @"Audio Thread"
#define NORMAL_THREAD_NAME @"Background Thread"
#define HIGH_THREAD_NAME @"Blocking Working Thread"
@implementation RunningThreadRunLoopPair
@synthesize runLoop, thread;
+ (RunningThreadRunLoopPair *)startNewWithThreadName:(NSString *)name {
ows_require(name != nil);
RunningThreadRunLoopPair *instance = [RunningThreadRunLoopPair new];
instance->thread = [[NSThread alloc] initWithTarget:instance selector:@selector(runLoopUntilCancelled) object:nil];
[instance->thread setName:name];
[instance->thread start];
[Operation asyncRunAndWaitUntilDone:^{
instance->runLoop = NSRunLoop.currentRunLoop;
}
onThread:instance->thread];
return instance;
}
- (void)terminate {
[thread cancel];
}
- (void)runLoopUntilCancelled {
NSThread *curThread = NSThread.currentThread;
NSRunLoop *curRunLoop = NSRunLoop.currentRunLoop;
while (!curThread.isCancelled) {
[curRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:5]];
}
}
@end
@implementation ThreadManager
static ThreadManager *sharedThreadManagerInternal;
+ (ThreadManager *)sharedThreadManager {
@synchronized(self) {
if (sharedThreadManagerInternal == nil) {
sharedThreadManagerInternal = [ThreadManager new];
sharedThreadManagerInternal->low = [RunningThreadRunLoopPair startNewWithThreadName:LOW_THREAD_NAME];
sharedThreadManagerInternal->normal = [RunningThreadRunLoopPair startNewWithThreadName:NORMAL_THREAD_NAME];
sharedThreadManagerInternal->high = [RunningThreadRunLoopPair startNewWithThreadName:HIGH_THREAD_NAME];
}
}
return sharedThreadManagerInternal;
}
+ (NSThread *)lowLatencyThread {
return self.sharedThreadManager->low.thread;
}
+ (NSRunLoop *)lowLatencyThreadRunLoop {
return self.sharedThreadManager->low.runLoop;
}
+ (NSThread *)normalLatencyThread {
return self.sharedThreadManager->normal.thread;
}
+ (NSRunLoop *)normalLatencyThreadRunLoop {
return self.sharedThreadManager->normal.runLoop;
}
+ (NSThread *)highLatencyThread {
return self.sharedThreadManager->high.thread;
}
+ (NSRunLoop *)highLatencyThreadRunLoop {
return self.sharedThreadManager->high.runLoop;
}
+ (void)terminate {
@synchronized(self) {
if (sharedThreadManagerInternal == nil)
return;
[sharedThreadManagerInternal->low terminate];
[sharedThreadManagerInternal->normal terminate];
[sharedThreadManagerInternal->high terminate];
sharedThreadManagerInternal = nil;
}
}
@end

View File

@ -1,38 +0,0 @@
#import <Foundation/Foundation.h>
#import "CollapsingFutures.h"
#import "Operation.h"
#import "Terminable.h"
@interface TimeUtil : NSObject
+ (NSTimeInterval)time;
/// Result has type Future(TypeOfValueReturnedByFunction)
+ (TOCFuture *)scheduleEvaluate:(Function)function
afterDelay:(NSTimeInterval)delay
onRunLoop:(NSRunLoop *)runLoop
unlessCancelled:(TOCCancelToken *)unlessCancelledToken;
/// Result has type Future(TypeOfValueReturnedByFunction)
+ (TOCFuture *)scheduleEvaluate:(Function)function
at:(NSDate *)date
onRunLoop:(NSRunLoop *)runLoop
unlessCancelled:(TOCCancelToken *)unlessCancelledToken;
+ (void)scheduleRun:(Action)action
afterDelay:(NSTimeInterval)delay
onRunLoop:(NSRunLoop *)runLoop
unlessCancelled:(TOCCancelToken *)unlessCancelledToken;
+ (void)scheduleRun:(Action)action
at:(NSDate *)date
onRunLoop:(NSRunLoop *)runLoop
unlessCancelled:(TOCCancelToken *)unlessCancelledToken;
+ (void)scheduleRun:(Action)action
periodically:(NSTimeInterval)interval
onRunLoop:(NSRunLoop *)runLoop
untilCancelled:(TOCCancelToken *)untilCancelledToken
andRunImmediately:(BOOL)shouldRunImmediately;
@end

View File

@ -1,143 +0,0 @@
#import "TimeUtil.h"
#import "Util.h"
@implementation TimeUtil
+ (NSTimeInterval)time {
return [[NSProcessInfo processInfo] systemUptime];
}
+ (TOCFuture *)scheduleEvaluate:(Function)function
afterDelay:(NSTimeInterval)delay
onRunLoop:(NSRunLoop *)runLoop
unlessCancelled:(TOCCancelToken *)unlessCancelledToken {
ows_require(function != NULL);
ows_require(runLoop != nil);
ows_require(delay >= 0);
TOCFutureSource *result = [TOCFutureSource futureSourceUntil:unlessCancelledToken];
Action evaler = ^{
[result trySetResult:function()];
};
[self scheduleHelper:evaler
withPeriod:delay
onRunLoop:runLoop
repeating:false
untilCancelled:unlessCancelledToken
andRunImmediately:NO];
return result.future;
}
+ (TOCFuture *)scheduleEvaluate:(Function)function
at:(NSDate *)date
onRunLoop:(NSRunLoop *)runLoop
unlessCancelled:(TOCCancelToken *)unlessCancelledToken {
ows_require(function != NULL);
ows_require(runLoop != nil);
ows_require(date != nil);
NSTimeInterval delay = [date timeIntervalSinceNow];
return [self scheduleEvaluate:function
afterDelay:MAX(0, delay)
onRunLoop:runLoop
unlessCancelled:unlessCancelledToken];
}
+ (void)scheduleRun:(Action)action
afterDelay:(NSTimeInterval)delay
onRunLoop:(NSRunLoop *)runLoop
unlessCancelled:(TOCCancelToken *)unlessCancelledToken {
ows_require(action != NULL);
ows_require(runLoop != nil);
ows_require(delay >= 0);
if (delay == INFINITY)
return;
[self scheduleHelper:action
withPeriod:delay
onRunLoop:runLoop
repeating:false
untilCancelled:unlessCancelledToken
andRunImmediately:NO];
}
+ (void)scheduleRun:(Action)action
at:(NSDate *)date
onRunLoop:(NSRunLoop *)runLoop
unlessCancelled:(TOCCancelToken *)unlessCancelledToken {
ows_require(action != NULL);
ows_require(runLoop != nil);
ows_require(date != nil);
NSTimeInterval delay = [date timeIntervalSinceNow];
[self scheduleRun:action afterDelay:MAX(0, delay) onRunLoop:runLoop unlessCancelled:unlessCancelledToken];
}
+ (void)scheduleRun:(Action)action
periodically:(NSTimeInterval)interval
onRunLoop:(NSRunLoop *)runLoop
untilCancelled:(TOCCancelToken *)untilCancelledToken
andRunImmediately:(BOOL)shouldRunImmediately {
ows_require(action != NULL);
ows_require(runLoop != nil);
ows_require(interval > 0);
[self scheduleHelper:action
withPeriod:interval
onRunLoop:runLoop
repeating:true
untilCancelled:untilCancelledToken
andRunImmediately:shouldRunImmediately];
}
+ (void)scheduleHelper:(Action)callback
withPeriod:(NSTimeInterval)interval
onRunLoop:(NSRunLoop *)runLoop
repeating:(bool)repeats
untilCancelled:(TOCCancelToken *)untilCancelledToken
andRunImmediately:(BOOL)shouldRunImmediately {
ows_require(callback != NULL);
ows_require(runLoop != nil);
ows_require(interval >= 0);
ows_require(!repeats || interval > 0);
if (untilCancelledToken.isAlreadyCancelled) {
return;
}
if (!repeats && interval == 0) {
callback();
return;
}
if (shouldRunImmediately) {
callback();
}
callback = [callback copy];
__block bool hasBeenCancelled = false;
__block NSObject *cancelLock = [NSObject new];
Operation *callbackUnlessCancelled = [Operation operation:^{
@synchronized(cancelLock) {
if (hasBeenCancelled)
return;
callback();
}
}];
NSTimer *timer = [NSTimer timerWithTimeInterval:interval
target:callbackUnlessCancelled
selector:[callbackUnlessCancelled selectorToRun]
userInfo:nil
repeats:repeats];
[runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
[untilCancelledToken whenCancelledDo:^{
@synchronized(cancelLock) {
hasBeenCancelled = true;
[timer invalidate];
}
}];
}
@end

View File

@ -3,15 +3,9 @@
//
#import <Foundation/Foundation.h>
#import "ArrayUtil.h"
#import "Crc32.h"
#import "DataUtil.h"
#import "DateUtil.h"
#import "DictionaryUtil.h"
#import "FunctionalUtil.h"
#import "FutureUtil.h"
#import "NumberUtil.h"
#import "Operation.h"
#import "StringUtil.h"
#import "TimeUtil.h"
#import "UIUtil.h"

View File

@ -1,12 +0,0 @@
#import <Foundation/Foundation.h>
@interface Zid : NSObject {
@private
NSData *data;
}
+ (instancetype)nullZid;
+ (Zid *)zidWithData:(NSData *)zidData;
- (NSData *)getData;
@end

View File

@ -1,24 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "Zid.h"
@implementation Zid
+ (Zid *)zidWithData:(NSData *)zidData {
ows_require(zidData != nil);
ows_require(zidData.length == 12);
Zid *s = [Zid new];
s->data = zidData;
return s;
}
+ (instancetype)nullZid {
NSMutableData *data = [NSMutableData dataWithLength:12];
return [self zidWithData:data];
}
- (NSData *)getData {
return data;
}
@end

View File

@ -1,51 +0,0 @@
#import <Foundation/Foundation.h>
/**
*
* Cyclic buffer is used to efficiently enqueue and dequeue blocks of data.
*
* Note that methods with 'volatile' in the name have results that can directly
* reference the queue's internal buffer, instead of returning a safe copy.
* The data returned by volatile methods must be used immediately and under the
* constraints that more data is not being enqueued at the time.
* Enqueueing data invalidates all previous volatile results, because the data they
* reference may have been overwritten.
*
*/
@interface CyclicalBuffer : NSObject {
@private
NSMutableData *buffer;
@private
uint32_t readOffset;
@private
uint32_t count;
}
/// Adds data to the buffer. The buffer will be resized if necessary.
- (void)enqueueData:(NSData *)data;
/// The number of bytes in the buffer.
- (NSUInteger)enqueuedLength;
/// Returns a view of the given length of bytes from the buffer.
/// Fails if there isn't enough enqueued data to satisfy the request.
- (NSData *)peekDataWithLength:(NSUInteger)length;
/// Extracts the given length of bytes from the buffer.
/// Fails if there isn't enough enqueued data to satisfy the request.
- (NSData *)dequeueDataWithLength:(NSUInteger)length;
/// Dequeues the given length of bytes from the buffer, without returning them.
/// Fails if there isn't enough enqueued data to satisfy the request.
- (void)discard:(NSUInteger)length;
/// Extracts the given length of bytes from the buffer, POTENTIALLY WITHOUT COPYING.
/// Fails if there isn't enough enqueued data to satisfy the request.
/// Consider result as invalid if more data is enqueued, because its contents may be overwritten.
- (NSData *)dequeuePotentialyVolatileDataWithLength:(NSUInteger)length;
/// Returns a volatile view of as much upcoming data-to-be-dequeued as possible, WITHOUT COPYING.
/// Consider result as invalid if more data is enqueued, because its contents may be overwritten.
- (NSData *)peekVolatileHeadOfData;
@end

View File

@ -1,109 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "CyclicalBuffer.h"
#import "Util.h"
#define INITIAL_CAPACITY 100 // The buffer size can not be longer than an unsigned int.
@implementation CyclicalBuffer
- (id)init {
if (self = [super init]) {
buffer = [NSMutableData dataWithLength:INITIAL_CAPACITY];
}
return self;
}
- (void)enqueueData:(NSData *)data {
ows_require(data != nil);
if (data.length == 0)
return;
NSUInteger incomingDataLength = data.length;
NSUInteger bufferCapacity = buffer.length;
NSUInteger writeOffset = (readOffset + count) % bufferCapacity;
NSUInteger bufferSpaceAvailable = bufferCapacity - count;
NSUInteger writeSlack = bufferCapacity - writeOffset;
if (bufferSpaceAvailable < incomingDataLength) {
NSUInteger readSlack = bufferCapacity - readOffset;
NSUInteger newCapacity = bufferCapacity * 2 + incomingDataLength;
NSMutableData *newBuffer = [NSMutableData dataWithLength:newCapacity];
[newBuffer replaceBytesInRange:NSMakeRange(0, MIN(readSlack, count))
withBytes:(uint8_t *)[buffer bytes] + readOffset];
if (readSlack < count) {
[newBuffer replaceBytesInRange:NSMakeRange(readSlack, count - readSlack)
withBytes:(uint8_t *)[buffer bytes]];
}
buffer = newBuffer;
bufferCapacity = newCapacity;
readOffset = 0;
writeOffset = count;
bufferSpaceAvailable = bufferCapacity - count;
writeSlack = bufferCapacity - writeOffset;
}
assert(bufferSpaceAvailable >= incomingDataLength);
[buffer replaceBytesInRange:NSMakeRange(writeOffset, MIN(writeSlack, incomingDataLength)) withBytes:[data bytes]];
if (incomingDataLength > writeSlack) {
[buffer replaceBytesInRange:NSMakeRange(0, incomingDataLength - writeSlack)
withBytes:(uint8_t *)[data bytes] + writeSlack];
}
count += data.length;
}
- (NSUInteger)enqueuedLength {
return count;
}
- (void)discard:(NSUInteger)length {
ows_require(length <= count);
count -= length;
readOffset = (readOffset + length) % (unsigned int)buffer.length;
}
- (NSData *)peekDataWithLength:(NSUInteger)length {
ows_require(length <= count);
if (length == 0)
return [NSData data];
NSUInteger readSlack = buffer.length - readOffset;
NSMutableData *result = [NSMutableData dataWithLength:length];
[result replaceBytesInRange:NSMakeRange(0, MIN(readSlack, length))
withBytes:(uint8_t *)[buffer bytes] + readOffset];
if (readSlack < length) {
[result replaceBytesInRange:NSMakeRange(readSlack, length - readSlack) withBytes:[buffer bytes]];
}
return result;
}
- (NSData *)dequeueDataWithLength:(NSUInteger)length {
NSData *result = [self peekDataWithLength:length];
[self discard:length];
return result;
}
- (NSData *)dequeuePotentialyVolatileDataWithLength:(NSUInteger)length {
NSUInteger readSlack = buffer.length - readOffset;
if (readSlack < length)
return [self dequeueDataWithLength:length];
NSData *result = [buffer subdataVolatileWithRange:NSMakeRange(readOffset, length)];
[self discard:length];
return result;
}
- (NSData *)peekVolatileHeadOfData {
NSUInteger capacity = buffer.length;
NSUInteger slack = capacity - readOffset;
return [buffer subdataVolatileWithRange:NSMakeRange(readOffset, MIN(count, slack))];
}
@end

View File

@ -1,19 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <CoreFoundation/CoreFoundation.h>
@interface PriorityQueue : NSObject {
@private
NSMutableArray *items;
}
@property (readonly, nonatomic, copy) NSComparator comparator;
+ (PriorityQueue *)priorityQueueAscendingWithComparator:(NSComparator)comparator;
- (void)enqueue:(id)item;
- (id)peek;
- (id)dequeue;
- (NSUInteger)count;
@end

View File

@ -1,68 +0,0 @@
#import "PriorityQueue.h"
@implementation PriorityQueue
+ (PriorityQueue *)priorityQueueAscendingWithComparator:(NSComparator)comparator {
ows_require(comparator != nil);
PriorityQueue *q = [PriorityQueue new];
q->_comparator = comparator;
q->items = [NSMutableArray array];
return q;
}
- (void)enqueue:(id)item {
NSUInteger curIndex = items.count;
[items addObject:item];
while (curIndex > 0) {
NSUInteger parentIndex = (curIndex - 1) >> 1;
id parentItem = items[parentIndex];
if (_comparator(item, parentItem) >= 0)
break;
[items setObject:parentItem atIndexedSubscript:curIndex];
[items setObject:item atIndexedSubscript:parentIndex];
curIndex = parentIndex;
}
}
- (id)peek {
requireState(items.count > 0);
return items[0];
}
- (id)dequeue {
requireState(items.count > 0);
id result = items[0];
// iteratively pull up smaller child until we hit the bottom of the heap
NSUInteger endangeredIndex = items.count - 1;
id endangeredItem = items[endangeredIndex];
NSUInteger i = 0;
while (true) {
NSUInteger childIndex1 = i * 2 + 1;
NSUInteger childIndex2 = i * 2 + 2;
if (childIndex1 >= endangeredIndex)
break;
NSUInteger smallerChildIndex =
_comparator(items[childIndex1], items[childIndex2]) <= 0 ? childIndex1 : childIndex2;
id smallerChild = items[smallerChildIndex];
bool useEndangered = _comparator(endangeredItem, smallerChild) <= 0;
if (useEndangered)
break;
[items setObject:smallerChild atIndexedSubscript:i];
i = smallerChildIndex;
}
// swap the item at the index to be removed into the new empty space at the bottom of heap
[items setObject:endangeredItem atIndexedSubscript:i];
[items removeObjectAtIndex:endangeredIndex];
return result;
}
- (NSUInteger)count {
return items.count;
}
@end

View File

@ -1,7 +0,0 @@
#import <Foundation/Foundation.h>
/// Cancels something when terminate is called.
/// It must be safe to call terminate multiple times.
@protocol Terminable <NSObject>
- (void)terminate;
@end

View File

@ -1,12 +0,0 @@
#import <Foundation/Foundation.h>
#import "Terminable.h"
@interface AnonymousTerminator : NSObject <Terminable> {
@private
bool alreadyCalled;
}
@property (readonly, nonatomic, copy) void (^terminateBlock)(void);
+ (AnonymousTerminator *)cancellerWithCancel:(void (^)(void))terminate;
@end

View File

@ -1,24 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "AnonymousTerminator.h"
@implementation AnonymousTerminator
+ (AnonymousTerminator *)cancellerWithCancel:(void (^)(void))terminate {
ows_require(terminate != nil);
AnonymousTerminator *c = [AnonymousTerminator new];
c->_terminateBlock = terminate;
return c;
}
- (void)terminate {
@synchronized(self) {
if (alreadyCalled)
return;
alreadyCalled = true;
}
_terminateBlock();
}
@end

View File

@ -1,11 +1,10 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "DiscardingLog.h"
#import "Release.h"
NSObject* churnLock(void);
bool _testChurnHelper(int (^condition)(), NSTimeInterval delay);
#define testPhoneNumber1 [PhoneNumber phoneNumberFromE164:@"+19027777777"]
#define testPhoneNumber2 [PhoneNumber phoneNumberFromE164:@"+19028888888"]
@ -16,8 +15,3 @@ bool _testChurnHelper(int (^condition)(), NSTimeInterval delay);
#define testEnvWith(options) [Release unitTestEnvironment:(@[options])]
#define testChurnUntil(condition, timeout) test(_testChurnHelper(^int{ return condition; }, timeout))
#define testChurnAndConditionMustStayTrue(condition, timeout) test(!_testChurnHelper(^int{ return !(condition); }, timeout))
NSData* increasingData(NSUInteger n);
NSData* increasingDataFrom(NSUInteger offset, NSUInteger n);
NSData* sineWave(double frequency, double sampleRate, NSUInteger sampleCount);
NSData* generatePseudoRandomData(NSUInteger length);

View File

@ -1,52 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "TestUtil.h"
#import "TimeUtil.h"
NSObject* churnLock(void) {
static NSObject* shared = nil;
if (shared == nil) {
shared = [NSObject new];
}
return shared;
}
bool _testChurnHelper(int (^condition)(), NSTimeInterval delay) {
NSTimeInterval t = [TimeUtil time] + delay;
while ([TimeUtil time] < t) {
@synchronized(churnLock()) {
if (condition()) return true;
}
[NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
}
@synchronized(churnLock()) {
return condition();
}
}
NSData* increasingData(NSUInteger n) {
return increasingDataFrom(0, n);
}
NSData* increasingDataFrom(NSUInteger offset, NSUInteger n) {
uint8_t v[n];
for (NSUInteger i = 0; i < n; i++)
v[i] = (uint8_t)((i+offset) & 0xFF);
return [NSData dataWithBytes:v length:n];
}
NSData* sineWave(double frequency, double sampleRate, NSUInteger sampleCount) {
double tau = 6.283;
int16_t samples[sampleCount];
for (NSUInteger i = 0; i < sampleCount; i++) {
samples[i] = (int16_t)(sin(frequency/sampleRate*i*tau)*(1<<15));
}
return [NSData dataWithBytes:samples length:sizeof(samples)];
}
NSData* generatePseudoRandomData(NSUInteger length) {
NSMutableData* r = [NSMutableData dataWithLength:length];
for (int i = 0; i < 16; i++) {
((uint8_t*)[r mutableBytes])[i] = (uint8_t)arc4random_uniform(256);
}
return r;
}

View File

@ -1,114 +0,0 @@
#import <XCTest/XCTest.h>
#import "DecayingSampleEstimator.h"
#import "TestUtil.h"
@interface DecayingSampleEstimatorTest : XCTestCase
@end
@implementation DecayingSampleEstimatorTest
-(void) testDecayingSampleEstimator {
DecayingSampleEstimator* e = [DecayingSampleEstimator decayingSampleEstimatorWithInitialEstimate:1.0 andDecayPerUnitSample:0.5];
test(e.currentEstimate == 1.0);
test([e decayRatePerUnitSample] == 0.5);
[e updateWithNextSample:2.0];
test(e.currentEstimate == 1.5);
test([e decayRatePerUnitSample] == 0.5);
[e updateWithNextSample:2.0];
test(e.currentEstimate == 1.75);
test([e decayRatePerUnitSample] == 0.5);
[e updateWithNextSample:1.75];
test(e.currentEstimate == 1.75);
[e updateWithNextSample:1.75];
test(e.currentEstimate == 1.75);
}
-(void) testDecayingSampleEstimatorForce {
DecayingSampleEstimator* e = [DecayingSampleEstimator decayingSampleEstimatorWithInitialEstimate:1.0 andDecayPerUnitSample:0.5];
test(e.currentEstimate == 1.0);
[e forceEstimateTo:5];
test(e.currentEstimate == 5);
test([e decayRatePerUnitSample] == 0.5);
}
-(void) testDecayingSampleEstimatorQuarter {
DecayingSampleEstimator* e = [DecayingSampleEstimator decayingSampleEstimatorWithInitialEstimate:1.0 andDecayPerUnitSample:0.75];
test(e.currentEstimate == 1.0);
test([e decayRatePerUnitSample] == 0.75);
[e updateWithNextSample:2.0];
test(e.currentEstimate == 1.75);
}
-(void) testDecayingSampleEstimatorCustomDecayPeriod {
DecayingSampleEstimator* e = [DecayingSampleEstimator decayingSampleEstimatorWithInitialEstimate:0 andDecayFactor:0.75 perNSamples:2];
test([e decayRatePerUnitSample] == 0.5);
[e updateWithNextSample:4];
[e updateWithNextSample:4];
test(e.currentEstimate == 3);
}
-(void) testDecayingSampleEstimatorWeighted {
DecayingSampleEstimator* e1 = [DecayingSampleEstimator decayingSampleEstimatorWithInitialEstimate:0.0 andDecayPerUnitSample:0.25];
DecayingSampleEstimator* e2 = [DecayingSampleEstimator decayingSampleEstimatorWithInitialEstimate:0.0 andDecayPerUnitSample:0.25];
[e1 updateWithNextSample:2.0 withSampleWeight:0.5];
[e1 updateWithNextSample:2.0 withSampleWeight:0.5];
[e2 updateWithNextSample:2.0];
test(ABS(e1.currentEstimate - e2.currentEstimate) < 0.00001);
[e1 updateWithNextSample:-1.0 withSampleWeight:2.0];
[e2 updateWithNextSample:-1.0];
[e2 updateWithNextSample:-1.0];
test(ABS(e1.currentEstimate - e2.currentEstimate) < 0.00001);
}
-(void) testDecayingSampleEstimatorCornerCase0 {
DecayingSampleEstimator* e = [DecayingSampleEstimator decayingSampleEstimatorWithInitialEstimate:1.0 andDecayPerUnitSample:0];
test([e decayRatePerUnitSample] == 0);
test(e.currentEstimate == 1.0);
[e updateWithNextSample:5.0];
test(e.currentEstimate == 1.0);
[e updateWithNextSample:535325.0];
test(e.currentEstimate == 1.0);
[e updateWithNextSample:-535325.0];
test(e.currentEstimate == 1.0);
[e updateWithNextSample:100.0 withSampleWeight:0];
test(e.currentEstimate == 1.0);
[e updateWithNextSample:200.0 withSampleWeight:100];
test(e.currentEstimate == 1.0);
[e updateWithNextSample:300.0 withSampleWeight:1];
test(e.currentEstimate == 1.0);
}
-(void) testDecayingSampleEstimatorCornerCase1 {
DecayingSampleEstimator* e = [DecayingSampleEstimator decayingSampleEstimatorWithInitialEstimate:1.0 andDecayPerUnitSample:1];
test([e decayRatePerUnitSample] == 1);
test(e.currentEstimate == 1.0);
[e updateWithNextSample:5.0];
test(e.currentEstimate == 5.0);
[e updateWithNextSample:535325.0];
test(e.currentEstimate == 535325.0);
[e updateWithNextSample:-535325.0];
test(e.currentEstimate == -535325.0);
[e updateWithNextSample:100.0 withSampleWeight:0.0001];
test(e.currentEstimate == 100.0);
[e updateWithNextSample:200.0 withSampleWeight:100];
test(e.currentEstimate == 200.0);
[e updateWithNextSample:300.0 withSampleWeight:1];
test(e.currentEstimate == 300.0);
[e updateWithNextSample:400.0 withSampleWeight:0];
test(e.currentEstimate == 300.0);
}
@end

View File

@ -1,25 +0,0 @@
#import <XCTest/XCTest.h>
#import "EventWindow.h"
#import "TestUtil.h"
@interface EventWindowTest : XCTestCase
@end
@implementation EventWindowTest
-(void) testEventWindow {
EventWindow* w = [EventWindow eventWindowWithWindowDuration:5];
test([w countAfterRemovingEventsBeforeWindowEndingAt:0] == 0);
[w addEventAtTime:4];
[w addEventAtTime:6];
[w addEventAtTime:8];
test([w countAfterRemovingEventsBeforeWindowEndingAt:8] == 3);
test([w countAfterRemovingEventsBeforeWindowEndingAt:10] == 2);
test([w countAfterRemovingEventsBeforeWindowEndingAt:12] == 1);
test([w countAfterRemovingEventsBeforeWindowEndingAt:14] == 0);
// going backwards not allowed
testThrows([w countAfterRemovingEventsBeforeWindowEndingAt:8]);
}
@end

View File

@ -1,5 +0,0 @@
#import <XCTest/XCTest.h>
@interface ConversionsTest : XCTestCase
@end

View File

@ -1,32 +0,0 @@
#import "ConversionsTest.h"
#import "Conversions.h"
#import "Util.h"
#import "TestUtil.h"
@implementation ConversionsTest
-(void) testDataWithBigEndianBytesOfUInt16 {
test([[NSData dataWithBigEndianBytesOfUInt16:0x1234u] isEqualToData:[(@[@0x12, @0x34]) ows_toUint8Data]]);
}
-(void) testDataWithBigEndianBytesOfUInt32 {
test([[NSData dataWithBigEndianBytesOfUInt32:0x12345678u] isEqualToData:[(@[@0x12, @0x34, @0x56, @0x78]) ows_toUint8Data]]);
}
-(void) testBigEndianUInt16At {
NSData* d = [@[@0, @1, @2, @0xFF, @3, @4] ows_toUint8Data];
test(0x1 == [d bigEndianUInt16At:0]);
test(0x102 == [d bigEndianUInt16At:1]);
test(0x2FF == [d bigEndianUInt16At:2]);
test(0xFF03 == [d bigEndianUInt16At:3]);
test(0x304 == [d bigEndianUInt16At:4]);
testThrows([d bigEndianUInt16At:5]);
}
-(void) testBigEndianUInt32At {
NSData* d = [@[@0, @1, @2, @0xFF, @3, @4] ows_toUint8Data];
test(0x000102FFu == [d bigEndianUInt32At:0]);
test(0x0102FF03u == [d bigEndianUInt32At:1]);
test(0x02FF0304u == [d bigEndianUInt32At:2]);
testThrows([d bigEndianUInt32At:3]);
}
@end

View File

@ -1,5 +0,0 @@
#import <XCTest/XCTest.h>
@interface Crc32Test : XCTestCase
@end

View File

@ -1,12 +0,0 @@
#import "Crc32Test.h"
#import "Crc32.h"
#import "TestUtil.h"
@implementation Crc32Test
-(void) testKnownCrc32 {
char* valText = "The quick brown fox jumps over the lazy dog";
NSData* val = [NSMutableData dataWithBytes:valText length:strlen(valText)];
test(0x414fa339 == [val crc32]);
}
@end

View File

@ -1,3 +1,7 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <XCTest/XCTest.h>
#import "Util.h"
#import "CryptoTools.h"
@ -8,51 +12,7 @@
@end
@implementation CryptoToolsTest
-(void) testIsEqualToData_TimingSafe {
test([[NSMutableData dataWithLength:0] isEqualToData_TimingSafe:[NSMutableData dataWithLength:0]]);
test([[NSMutableData dataWithLength:1] isEqualToData_TimingSafe:[NSMutableData dataWithLength:1]]);
test(![[NSMutableData dataWithLength:1] isEqualToData_TimingSafe:[NSMutableData dataWithLength:0]]);
test([[@"01020304" decodedAsHexString] isEqualToData_TimingSafe:[@"01020304" decodedAsHexString]]);
test(![[@"01020305" decodedAsHexString] isEqualToData_TimingSafe:[@"01020304" decodedAsHexString]]);
test(![[@"05020305" decodedAsHexString] isEqualToData_TimingSafe:[@"01020304" decodedAsHexString]]);
test(![[@"05020304" decodedAsHexString] isEqualToData_TimingSafe:[@"01020304" decodedAsHexString]]);
test(![[@"01050304" decodedAsHexString] isEqualToData_TimingSafe:[@"01020304" decodedAsHexString]]);
}
-(void) testKnownHmacSha1 {
char* keyText = "key";
char* valText = "The quick brown fox jumps over the lazy dog";
NSData* key = [NSMutableData dataWithBytes:keyText length:strlen(keyText)];
NSData* val = [NSMutableData dataWithBytes:valText length:strlen(valText)];
NSData* expected = [@"de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9" decodedAsHexString];
NSData* actual = [val hmacWithSha1WithKey:key];
test([actual isEqualToData:expected]);
}
-(void) testKnownHmacSha256 {
char* keyText = "key";
char* valText = "The quick brown fox jumps over the lazy dog";
NSData* key = [NSMutableData dataWithBytes:keyText length:strlen(keyText)];
NSData* val = [NSMutableData dataWithBytes:valText length:strlen(valText)];
NSData* expected = [@"f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8" decodedAsHexString];
NSData* actual = [val hmacWithSha256WithKey:key];
test([actual isEqualToData:expected]);
}
-(void) testAesCipherBlockChainingPadding {
NSData* iv = [@"000102030405060708090A0B0C0D0E0F" decodedAsHexString];
NSData* plain =[@"10b80d8098f0283a820e" decodedAsHexString];
NSData* key =[@"2b7e151628aed2a6abf7158809cf4f3c" decodedAsHexString];
NSData* cipher = [plain encryptWithAesInCipherBlockChainingModeWithPkcs7PaddingWithKey:key andIv:iv];
test(cipher.length % 16 == 0);
NSData* replain = [cipher decryptWithAesInCipherBlockChainingModeWithPkcs7PaddingWithKey:key andIv:iv];
test(plain.length == replain.length);
}
-(void) testKnownSha256 {
char* valText = "The quick brown fox jumps over the lazy dog";
NSData* val = [NSMutableData dataWithBytes:valText length:strlen(valText)];
NSData* expected = [@"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592" decodedAsHexString];
NSData* actual = [val hashWithSha256];
test([actual isEqualToData:expected]);
}
-(void) testRandomForVariance {
NSData* d = [CryptoTools generateSecureRandomData:8];
NSData* d2 = [CryptoTools generateSecureRandomData:8];
@ -64,78 +24,4 @@
test(![d isEqualToData:d2]);
}
-(void) testRandomUInt16GenerationForVariance{
uint16_t a = [CryptoTools generateSecureRandomUInt16];
uint16_t b = [CryptoTools generateSecureRandomUInt16];
uint16_t c = [CryptoTools generateSecureRandomUInt16];
uint16_t d = [CryptoTools generateSecureRandomUInt16];
// extremely unlikely to fail if any reasonable amount of entropy is generated
BOOL same =((a==b) && (a==c) && (a==d));
test (!same);
}
-(void) testGenerateSecureRandomUInt32_varies {
NSMutableSet* s = [NSMutableSet new];
for (uint i = 0; i < 10; i++) {
[s addObject:@([CryptoTools generateSecureRandomUInt32])];
}
// Note: expected false negative rate is approximately once per hundred million runs
test(s.count == 10);
}
-(void) testKnownAesCipherFeedback {
NSData* iv = [@"000102030405060708090a0b0c0d0e0f" decodedAsHexString];
NSData* plain =[@"6bc1bee22e409f96e93d7e117393172a" decodedAsHexString];
NSData* cipher =[@"3b3fd92eb72dad20333449f8e83cfb4a" decodedAsHexString];
NSData* key =[@"2b7e151628aed2a6abf7158809cf4f3c" decodedAsHexString];
test([[plain encryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] isEqualToData:cipher]);
test([[cipher decryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] isEqualToData:plain]);
}
-(void) testPerturbedAesCipherFeedbackInverts {
for (int repeat = 0; repeat < 100; repeat++) {
NSData* iv = generatePseudoRandomData(16);
NSData* input = generatePseudoRandomData(16);
NSData* key = generatePseudoRandomData(16);
test([[[input encryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] decryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] isEqualToData:input]);
test([[[input decryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] encryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] isEqualToData:input]);
}
}
-(void) testKnownAesCounter {
NSData* iv = [@"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" decodedAsHexString];
NSData* plain =[@"6bc1bee22e409f96e93d7e117393172a" decodedAsHexString];
NSData* cipher =[@"874d6191b620e3261bef6864990db6ce" decodedAsHexString];
NSData* key =[@"2b7e151628aed2a6abf7158809cf4f3c" decodedAsHexString];
test([[plain encryptWithAesInCounterModeWithKey:key andIv:iv] isEqualToData:cipher]);
test([[cipher decryptWithAesInCounterModeWithKey:key andIv:iv] isEqualToData:plain]);
}
-(void) testAesCounterEndianness {
NSData* iv = [@"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" decodedAsHexString];
NSData* plain =[@"6bc1bee22e409f96e93d7e117393172ab1661dadd153b245034f1fb3655dc560" decodedAsHexString];
NSData* cipher =[@"874d6191b620e3261bef6864990db6ce874d6191b620e3261bef6864990db6ce" decodedAsHexString];
NSData* key =[@"2b7e151628aed2a6abf7158809cf4f3c" decodedAsHexString];
test([[plain encryptWithAesInCounterModeWithKey:key andIv:iv] isEqualToData:cipher]);
test([[cipher decryptWithAesInCounterModeWithKey:key andIv:iv] isEqualToData:plain]);
}
-(void) testPerturbedAesCounterInverts {
for (int repeat = 0; repeat < 100; repeat++) {
NSData* iv = generatePseudoRandomData(16);
NSData* input = generatePseudoRandomData(16);
NSData* key = generatePseudoRandomData(16);
test([[[input encryptWithAesInCounterModeWithKey:key andIv:iv] decryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] isEqualToData:input]);
test([[[input decryptWithAesInCounterModeWithKey:key andIv:iv] encryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] isEqualToData:input]);
}
}
-(void) testComputeKnownOtp {
test([[CryptoTools computeOtpWithPassword:@"password" andCounter:123] isEqualToString:@"SiYZc8Xg6KSmCECSImVSmjnRNfc="]);
}
@end

View File

@ -1,5 +0,0 @@
#import <XCTest/XCTest.h>
@interface CyclicalBufferTest : XCTestCase
@end

View File

@ -1,121 +0,0 @@
#import "CyclicalBufferTest.h"
#import "CyclicalBuffer.h"
#import "TestUtil.h"
@implementation CyclicalBufferTest
-(void) testEnqueueData {
CyclicalBuffer* c = [CyclicalBuffer new];
test([c enqueuedLength] == 0);
[c enqueueData:increasingData(5)];
test([c enqueuedLength] == 5);
// empty enqueueData does nothing
[c enqueueData:[NSData data]];
test([c enqueuedLength] == 5);
// nil enqueueData fails without ruining everything
testThrows([c enqueueData:nil]);
test([c enqueuedLength] == 5);
[c enqueueData:increasingData(5)];
test([c enqueuedLength] == 10);
[c enqueueData:increasingData(5000)];
test([c enqueuedLength] == 5010);
}
-(void) testGrow {
CyclicalBuffer* c = [CyclicalBuffer new];
NSUInteger n = 10000;
for (NSUInteger i = 0; i < n; i++) {
test([c enqueuedLength] == i*4);
[c enqueueData:increasingDataFrom(i*6, 6)];
NSData* d = [c dequeueDataWithLength:2];
test([d isEqualToData:increasingDataFrom(i*2, 2)]);
}
test([c enqueuedLength] == n*4);
test([[c dequeueDataWithLength:n*4] isEqualToData:increasingDataFrom(n*2, n*4)]);
}
-(void) testCycle {
CyclicalBuffer* c = [CyclicalBuffer new];
[c enqueueData:[NSMutableData dataWithLength:200]];
for (int i = 0; i < 100; i++) {
[c enqueueData:[NSMutableData dataWithLength:11]];
test([[c dequeueDataWithLength:13] isEqualToData:[NSMutableData dataWithLength:13]]);
}
}
-(void) testDequeueStable {
CyclicalBuffer* c = [CyclicalBuffer new];
[c enqueueData:increasingData(20)];
[c enqueueData:[NSMutableData dataWithLength:200]];
NSData* d = [c dequeueDataWithLength:20];
for (int i = 0; i < 100; i++) {
[c enqueueData:[NSMutableData dataWithLength:11]];
test([[c dequeueDataWithLength:13] isEqualToData:[NSMutableData dataWithLength:13]]);
}
test([d isEqualToData:increasingData(20)]);
}
-(void) testCycleVolatile {
CyclicalBuffer* c = [CyclicalBuffer new];
[c enqueueData:increasingData(200)];
for (NSUInteger i = 0; i < 100; i++) {
[c enqueueData:increasingDataFrom(200+i*11, 11)];
test([[c dequeuePotentialyVolatileDataWithLength:13] isEqualToData:increasingDataFrom(i*13, 13)]);
}
}
-(void) testDequeue {
CyclicalBuffer* c = [CyclicalBuffer new];
[c enqueueData:increasingData(5000)];
test([[c dequeueDataWithLength:0] length] == 0);
test([c enqueuedLength] == 5000);
test([[c dequeueDataWithLength:5] isEqualToData:increasingData(5)]);
test([c enqueuedLength] == 4995);
test([[c dequeueDataWithLength:1] isEqualToData:increasingDataFrom(5, 1)]);
test([c enqueuedLength] == 4994);
testThrows([c dequeueDataWithLength:4995]);
test([c enqueuedLength] == 4994);
test([[c dequeueDataWithLength:4994] isEqualToData:increasingDataFrom(6, 4994)]);
test([c enqueuedLength] == 0);
}
-(void) testDiscard {
CyclicalBuffer* c = [CyclicalBuffer new];
[c enqueueData:increasingData(5000)];
[c discard:4000];
test([c enqueuedLength] == 1000);
test([[c dequeueDataWithLength:100] isEqualToData:increasingDataFrom(4000, 100)]);
testThrows([c discard:4325663]);
testThrows([c discard:901]);
[c discard:0];
testThrows([c discard:901]);
[c discard:900];
test([c enqueuedLength] == 0);
testThrows([c discard:1]);
[c discard:0];
}
-(void) testDiscardStable {
CyclicalBuffer* c = [CyclicalBuffer new];
[c enqueueData:increasingData(200)];
for (NSUInteger i = 1; i <= 100; i++) {
[c enqueueData:increasingData(11)];
[c discard:13];
test([c enqueuedLength] == 200-2*i);
}
}
-(void) testDequeueVolatile {
CyclicalBuffer* c = [CyclicalBuffer new];
[c enqueueData:increasingData(5000)];
test([[c dequeuePotentialyVolatileDataWithLength:0] length] == 0);
test([c enqueuedLength] == 5000);
test([[c dequeuePotentialyVolatileDataWithLength:5] isEqualToData:increasingData(5)]);
test([c enqueuedLength] == 4995);
test([[c dequeuePotentialyVolatileDataWithLength:1] isEqualToData:increasingDataFrom(5, 1)]);
test([c enqueuedLength] == 4994);
testThrows([c dequeuePotentialyVolatileDataWithLength:4995]);
test([c enqueuedLength] == 4994);
test([[c dequeuePotentialyVolatileDataWithLength:4994] isEqualToData:increasingDataFrom(6, 4994)]);
test([c enqueuedLength] == 0);
}
@end

View File

@ -1,190 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "FutureUtil.h"
#import "TestUtil.h"
#import "ThreadManager.h"
#import "TimeUtil.h"
#import <TwistedOakCollapsingFutures/CollapsingFutures.h>
#import <XCTest/XCTest.h>
@interface FutureUtilTest : XCTestCase
@end
@implementation FutureUtilTest
- (void)testOperationTry {
TOCFuture *f = [TOCFuture operationTry:^TOCFuture *(TOCCancelToken *_) {
@throw @"Fail";
}](nil);
test([f isEqualToFuture:[TOCFuture futureWithFailure:@"Fail"]]);
}
- (void)testThenValue {
test([[[TOCFuture futureWithFailure:@0] thenValue:@""] isEqualToFuture:[TOCFuture futureWithFailure:@0]]);
test([[[TOCFuture futureWithResult:@1] thenValue:@""] isEqualToFuture:[TOCFuture futureWithResult:@""]]);
test([[TOCFutureSource new].future thenValue:@""].isIncomplete);
}
- (void)testFinallyTry {
test([[[TOCFuture futureWithResult:@1] finallyTry:^(TOCFuture *f) {
return @"";
}] isEqualToFuture:[TOCFuture futureWithResult:@""]]);
test([[[TOCFuture futureWithFailure:@0] finallyTry:^(TOCFuture *f) {
return @"";
}] isEqualToFuture:[TOCFuture futureWithResult:@""]]);
test([[TOCFutureSource new]
.future finallyTry:^(TOCFuture *f) {
return @"";
}].isIncomplete);
test([[[TOCFuture futureWithResult:@1] finallyTry:^id(TOCFuture *f) {
@throw @"";
}] isEqualToFuture:[TOCFuture futureWithFailure:@""]]);
test([[[TOCFuture futureWithFailure:@0] finallyTry:^id(TOCFuture *f) {
@throw @"";
}] isEqualToFuture:[TOCFuture futureWithFailure:@""]]);
test([[TOCFutureSource new]
.future finallyTry:^id(TOCFuture *f) {
@throw @"";
}].isIncomplete);
}
- (void)testThenTry {
test([[[TOCFuture futureWithResult:@1] thenTry:^(id f) {
return @"";
}] isEqualToFuture:[TOCFuture futureWithResult:@""]]);
test([[[TOCFuture futureWithFailure:@0] thenTry:^(id f) {
return @"";
}] isEqualToFuture:[TOCFuture futureWithFailure:@0]]);
test([[TOCFutureSource new]
.future thenTry:^(id f) {
return @"";
}].isIncomplete);
test([[[TOCFuture futureWithResult:@1] thenTry:^id(id f) {
@throw @"";
}] isEqualToFuture:[TOCFuture futureWithFailure:@""]]);
test([[[TOCFuture futureWithFailure:@0] thenTry:^id(id f) {
@throw @"";
}] isEqualToFuture:[TOCFuture futureWithFailure:@0]]);
test([[TOCFutureSource new]
.future thenTry:^id(id f) {
@throw @"";
}].isIncomplete);
}
- (void)testCatchTry {
test([[[TOCFuture futureWithResult:@1] catchTry:^(id f) {
return @"";
}] isEqualToFuture:[TOCFuture futureWithResult:@1]]);
test([[[TOCFuture futureWithFailure:@0] catchTry:^(id f) {
return @"";
}] isEqualToFuture:[TOCFuture futureWithResult:@""]]);
test([[TOCFutureSource new]
.future catchTry:^(id f) {
return @"";
}].isIncomplete);
test([[[TOCFuture futureWithResult:@1] catchTry:^id(id f) {
@throw @"";
}] isEqualToFuture:[TOCFuture futureWithResult:@1]]);
test([[[TOCFuture futureWithFailure:@0] catchTry:^id(id f) {
@throw @"";
}] isEqualToFuture:[TOCFuture futureWithFailure:@""]]);
test([[TOCFutureSource new]
.future catchTry:^id(id f) {
@throw @"";
}].isIncomplete);
}
- (void)testRetry_pass {
__block NSUInteger repeat = 0;
__block NSUInteger evalCount = 0;
TOCUntilOperation op = ^(TOCCancelToken *c) {
repeat += 1;
return [TimeUtil scheduleEvaluate:^id {
evalCount++;
return @YES;
}
afterDelay:0.35
onRunLoop:[ThreadManager normalLatencyThreadRunLoop]
unlessCancelled:c];
};
TOCFuture *f = [TOCFuture retry:op upToNTimes:4 withBaseTimeout:0.5 / 8 andRetryFactor:2 untilCancelled:nil];
testChurnUntil(!f.isIncomplete, 500.0);
test(repeat == 3 || repeat == 4);
test(evalCount == 1);
test(f.hasResult);
test([[f forceGetResult] isEqual:@YES]);
}
- (void)testRetry_fail {
__block NSUInteger repeat = 0;
__block NSUInteger evalCount = 0;
TOCUntilOperation op = ^(TOCCancelToken *c) {
repeat += 1;
return [TimeUtil scheduleEvaluate:^{
evalCount++;
return [TOCFuture futureWithFailure:@13];
}
afterDelay:0.1
onRunLoop:[ThreadManager normalLatencyThreadRunLoop]
unlessCancelled:c];
};
TOCFuture *f = [TOCFuture retry:op upToNTimes:4 withBaseTimeout:0.5 / 8 andRetryFactor:2 untilCancelled:nil];
testChurnUntil(!f.isIncomplete, 5.0);
test(repeat >= 1);
test(evalCount >= 1);
test(f.hasFailed);
test([f.forceGetFailure isEqual:@13]);
}
- (void)testRetry_timeout {
__block NSUInteger repeat = 0;
__block NSUInteger evalCount = 0;
TOCUntilOperation op = ^(TOCCancelToken *c) {
repeat += 1;
return [TimeUtil scheduleEvaluate:^id {
evalCount++;
return @YES;
}
afterDelay:0.5
onRunLoop:[ThreadManager normalLatencyThreadRunLoop]
unlessCancelled:c];
};
TOCFuture *f = [TOCFuture retry:op upToNTimes:2 withBaseTimeout:0.5 / 8 andRetryFactor:2 untilCancelled:nil];
testChurnUntil(!f.isIncomplete, 5.0);
test(repeat == 2);
test(evalCount == 0);
test(f.hasFailedWithTimeout);
}
- (void)testRetry_cancel {
TOCCancelTokenSource *s = [TOCCancelTokenSource new];
__block NSUInteger repeat = 0;
__block NSUInteger evalCount = 0;
TOCUntilOperation op = ^(TOCCancelToken *c) {
repeat += 1;
[TimeUtil scheduleRun:^{
[s cancel];
}
afterDelay:0.1
onRunLoop:[ThreadManager normalLatencyThreadRunLoop]
unlessCancelled:nil];
return [TimeUtil scheduleEvaluate:^id {
evalCount++;
return @YES;
}
afterDelay:0.5
onRunLoop:[ThreadManager normalLatencyThreadRunLoop]
unlessCancelled:c];
};
TOCFuture *f = [TOCFuture retry:op upToNTimes:2 withBaseTimeout:0.5 / 8 andRetryFactor:2 untilCancelled:s.token];
testChurnUntil(!f.isIncomplete, 5.0);
test(repeat == 2);
test(evalCount == 0);
test(f.hasFailedWithCancel);
}
@end

View File

@ -1,3 +1,7 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "UtilTest.h"
#import "Util.h"
#import "TestUtil.h"
@ -22,130 +26,6 @@
test([NumberUtil smallestIntegerThatIsAtLeast:21 andIsAMultipleOf:20] == 40);
}
-(void) testArrayToUint8Data {
test([[(@[]) ows_toUint8Data] length] == 0);
NSData* d = [@[@0, @1] ows_toUint8Data];
test(d.length == 2);
test(((uint8_t*)[d bytes])[0] == 0);
test(((uint8_t*)[d bytes])[1] == 1);
}
-(void) testArrayConcatDatas {
NSData* d1 = [@[@0, @1] ows_toUint8Data];
NSData* d2 = [@[@3, @4] ows_toUint8Data];
NSData* d3 = [@[@6, @7] ows_toUint8Data];
test([[@[] ows_concatDatas] isEqualToData:[(@[]) ows_toUint8Data]]);
test([[@[d1] ows_concatDatas] isEqualToData:d1]);
test([[(@[d1, d2, d3]) ows_concatDatas] isEqualToData:[(@[@0, @1, @3, @4, @6, @7]) ows_toUint8Data]]);
}
-(void) testDatadDecodedAsUtf8 {
testThrows([[(@[@0xC3, @0x28]) ows_toUint8Data] decodedAsUtf8]);
NSString* ab = [[(@[@97, @98]) ows_toUint8Data] decodedAsUtf8];
NSString* ab0 = [[(@[@97, @98, @0]) ows_toUint8Data] decodedAsUtf8];
test([ab isEqualToString:@"ab"]);
test([ab0 isEqualToString:@"ab\0"]);
test(![ab0 isEqualToString:ab]);
}
-(void) testTryFindFirstIndexOf {
NSData* d = [@[@0, @1, @2, @3, @4, @5] ows_toUint8Data];
NSData* d34 = [@[@3, @4] ows_toUint8Data];
NSData* d67 = [@[@6, @7] ows_toUint8Data];
NSData* d01 = [@[@0, @1] ows_toUint8Data];
NSData* d02 = [@[@0, @2] ows_toUint8Data];
test([[d tryFindIndexOf:[NSData data]] intValue] == 0);
test([d tryFindIndexOf:d].intValue == 0);
test([d tryFindIndexOf:d01].intValue == 0);
test([d tryFindIndexOf:d02] == nil);
test([d tryFindIndexOf:d34].intValue == 3);
test([d34 tryFindIndexOf:d] == nil);
test([d tryFindIndexOf:d67] == nil);
}
-(void) testDatadDecodedAsAscii {
testThrows([[(@[@97, @0xAA]) ows_toUint8Data] decodedAsAscii]);
NSString* ab = [[(@[@97, @98]) ows_toUint8Data] decodedAsAscii];
NSString* ab0 = [[(@[@97, @98, @0]) ows_toUint8Data] decodedAsAscii];
test([ab isEqualToString:@"ab"]);
test([ab0 isEqualToString:@"ab\0"]);
test(![ab0 isEqualToString:ab]);
}
-(void) testDatadDecodedAsAsciiReplacingErrorsWithDots {
test([[[(@[@97, @98]) ows_toUint8Data] decodedAsAsciiReplacingErrorsWithDots] isEqualToString:@"ab"]);
test([[[(@[@97, @98, @0, @127, @250]) ows_toUint8Data] decodedAsAsciiReplacingErrorsWithDots] isEqualToString:@"ab..."]);
}
-(void) testDataSkip {
NSData* d = [@[@0, @1, @2, @3] ows_toUint8Data];
test([[d skip:0] isEqualToData:d]);
test([[d skip:1] isEqualToData:[(@[@1, @2, @3]) ows_toUint8Data]]);
test([[d skip:3] isEqualToData:[@[@3] ows_toUint8Data]]);
test([[d skip:4] length] == 0);
testThrows([d skip:5]);
// stable
NSMutableData* m = [NSMutableData dataWithLength:2];
NSData* b = [m skip:1];
NSData* b2 = [m skip:0];
[m setUint8At:0 to:1];
[m setUint8At:1 to:1];
test([b uint8At:0] == 0);
test([b2 uint8At:0] == 0);
}
-(void) testDataTake {
NSData* d = [@[@0, @1, @2, @3] ows_toUint8Data];
test([[d take:0] length] == 0);
test([[d take:1] isEqualToData:[(@[@0]) ows_toUint8Data]]);
test([[d take:3] isEqualToData:[(@[@0, @1, @2]) ows_toUint8Data]]);
test([[d take:4] isEqualToData:d]);
testThrows([d take:5]);
// stable
NSMutableData* m = [NSMutableData dataWithLength:2];
NSData* b = [m take:1];
NSData* b2 = [m take:2];
[m setUint8At:0 to:1];
[m setUint8At:1 to:1];
test([b uint8At:0] == 0);
test([b2 uint8At:0] == 0);
}
-(void) testDataSkipLast {
NSData* d = [@[@0, @1, @2, @3] ows_toUint8Data];
test([[d skipLast:0] isEqualToData:d]);
test([[d skipLast:1] isEqualToData:[(@[@0, @1, @2]) ows_toUint8Data]]);
test([[d skipLast:3] isEqualToData:[@[@0] ows_toUint8Data]]);
test([[d skipLast:4] length] == 0);
testThrows([d skipLast:5]);
// stable
NSMutableData* m = [NSMutableData dataWithLength:2];
NSData* b = [m skipLast:1];
NSData* b2 = [m skipLast:0];
[m setUint8At:0 to:1];
[m setUint8At:1 to:1];
test([b uint8At:0] == 0);
test([b2 uint8At:0] == 0);
}
-(void) testDataTakeLast {
NSData* d = [@[@0, @1, @2, @3] ows_toUint8Data];
test([[d takeLast:0] length] == 0);
test([[d takeLast:1] isEqualToData:[(@[@3]) ows_toUint8Data]]);
test([[d takeLast:3] isEqualToData:[(@[@1, @2, @3]) ows_toUint8Data]]);
test([[d takeLast:4] isEqualToData:d]);
testThrows([d takeLast:5]);
// stable
NSMutableData* m = [NSMutableData dataWithLength:2];
NSData* b = [m takeLast:1];
NSData* b2 = [m takeLast:2];
[m setUint8At:0 to:1];
[m setUint8At:1 to:1];
test([b uint8At:0] == 0);
test([b2 uint8At:0] == 0);
}
-(void) testCongruentDifferenceMod2ToThe16 {
test([NumberUtil congruentDifferenceMod2ToThe16From:1 to:0xFFFF] == -2);
test([NumberUtil congruentDifferenceMod2ToThe16From:1 to:10] == 9);
@ -154,132 +34,6 @@
test([NumberUtil congruentDifferenceMod2ToThe16From:0x8000 to:0] == -0x8000);
test([NumberUtil congruentDifferenceMod2ToThe16From:0 to:0] == 0);
}
-(void) testSubdataVolatileAgainstReference {
NSData* d = increasingData(10);
for (NSUInteger i = 0; i < 10; i++) {
for (NSUInteger j = 0; j < 10-i; j++) {
NSData* s1 = [d subdataVolatileWithRange:NSMakeRange(i, j)];
NSData* s2 = [d subdataWithRange:NSMakeRange(i, j)];
test([s1 isEqualToData:s2]);
}
}
}
-(void) testSubdataVolatileErrorCases {
NSData* d = increasingData(10);
[d subdataVolatileWithRange:NSMakeRange(0, 0)];
[d subdataVolatileWithRange:NSMakeRange(0, 10)];
[d subdataVolatileWithRange:NSMakeRange(10, 0)];
testThrows([d subdataVolatileWithRange:NSMakeRange(0, 11)]);
testThrows([d subdataVolatileWithRange:NSMakeRange(11, 0)]);
testThrows([d subdataVolatileWithRange:NSMakeRange(1, 10)]);
testThrows([d subdataVolatileWithRange:NSMakeRange(10, 1)]);
// potential wraparound cases
testThrows([d subdataVolatileWithRange:NSMakeRange(NSUIntegerMax, 1)]);
testThrows([d subdataVolatileWithRange:NSMakeRange(1, NSUIntegerMax)]);
}
-(void) testDataSkipVolatile {
NSData* d = [@[@0, @1, @2, @3] ows_toUint8Data];
test([[d skipVolatile:0] isEqualToData:d]);
test([[d skipVolatile:1] isEqualToData:[(@[@1, @2, @3]) ows_toUint8Data]]);
test([[d skipVolatile:3] isEqualToData:[@[@3] ows_toUint8Data]]);
test([[d skipVolatile:4] length] == 0);
testThrows([d skipVolatile:5]);
}
-(void) testDataTakeVolatile {
NSData* d = [@[@0, @1, @2, @3] ows_toUint8Data];
test([[d takeVolatile:0] length] == 0);
test([[d takeVolatile:1] isEqualToData:[(@[@0]) ows_toUint8Data]]);
test([[d takeVolatile:3] isEqualToData:[(@[@0, @1, @2]) ows_toUint8Data]]);
test([[d takeVolatile:4] isEqualToData:d]);
testThrows([d takeVolatile:5]);
}
-(void) testDataSkipLastVolatile {
NSData* d = [@[@0, @1, @2, @3] ows_toUint8Data];
test([[d skipLastVolatile:0] isEqualToData:d]);
test([[d skipLastVolatile:1] isEqualToData:[(@[@0, @1, @2]) ows_toUint8Data]]);
test([[d skipLastVolatile:3] isEqualToData:[@[@0] ows_toUint8Data]]);
test([[d skipLastVolatile:4] length] == 0);
testThrows([d skipLastVolatile:5]);
}
-(void) testDataTakeLastVolatile {
NSData* d = [@[@0, @1, @2, @3] ows_toUint8Data];
test([[d takeLastVolatile:0] length] == 0);
test([[d takeLastVolatile:1] isEqualToData:[(@[@3]) ows_toUint8Data]]);
test([[d takeLastVolatile:3] isEqualToData:[(@[@1, @2, @3]) ows_toUint8Data]]);
test([[d takeLastVolatile:4] isEqualToData:d]);
testThrows([d takeLastVolatile:5]);
}
-(void) testDataUint8At {
NSData* d = [@[@0, @1, @2, @3] ows_toUint8Data];
test([d uint8At:0] == 0);
test([d uint8At:1] == 1);
test([d uint8At:2] == 2);
test([d uint8At:3] == 3);
testThrows([d uint8At:4]);
}
-(void) testDataSetUint8At {
NSMutableData* d = [NSMutableData dataWithLength:4];
[d setUint8At:0 to:11];
[d setUint8At:1 to:12];
[d setUint8At:2 to:13];
[d setUint8At:3 to:14];
testThrows([d setUint8At:4 to:15]);
test([d isEqualToData:[(@[@11, @12, @13, @14]) ows_toUint8Data]]);
}
-(void) testMutableDataReplaceBytesStartingAt {
NSMutableData* d = [NSMutableData dataWithLength:6];
NSData* d2 = [@[@1, @2, @3] ows_toUint8Data];
testThrows([d replaceBytesStartingAt:0 withData:nil]);
testThrows([d replaceBytesStartingAt:4 withData:d2]);
[d replaceBytesStartingAt:0 withData:d2];
test([d isEqualToData:[(@[@1, @2, @3, @0, @0, @0]) ows_toUint8Data]]);
[d replaceBytesStartingAt:2 withData:d2];
test([d isEqualToData:[(@[@1, @2, @1, @2, @3, @0]) ows_toUint8Data]]);
[d replaceBytesStartingAt:3 withData:d2];
test([d isEqualToData:[(@[@1, @2, @1, @1, @2, @3]) ows_toUint8Data]]);
}
-(void) testStringEncodedAsUtf8 {
test([@"ab".encodedAsUtf8 isEqualToData:[(@[@97, @98]) ows_toUint8Data]]);
}
-(void) testStringEncodedAsAscii {
test([@"ab".encodedAsAscii isEqualToData:[(@[@97, @98]) ows_toUint8Data]]);
testThrows(@"√".encodedAsAscii);
}
-(void) testBase64EncodeKnown {
test([@"".encodedAsUtf8.encodedAsBase64 isEqualToString:@""]);
test([@"f".encodedAsUtf8.encodedAsBase64 isEqualToString:@"Zg=="]);
test([@"fo".encodedAsUtf8.encodedAsBase64 isEqualToString:@"Zm8="]);
test([@"foo".encodedAsUtf8.encodedAsBase64 isEqualToString:@"Zm9v"]);
test([@"foob".encodedAsUtf8.encodedAsBase64 isEqualToString:@"Zm9vYg=="]);
test([@"fooba".encodedAsUtf8.encodedAsBase64 isEqualToString:@"Zm9vYmE="]);
test([@"foobar".encodedAsUtf8.encodedAsBase64 isEqualToString:@"Zm9vYmFy"]);
}
-(void) testBase64DecodeKnown {
test([@"".encodedAsUtf8 isEqualToData:[@"" decodedAsBase64Data]]);
test([@"f".encodedAsUtf8 isEqualToData:[@"Zg==" decodedAsBase64Data]]);
test([@"fo".encodedAsUtf8 isEqualToData:[@"Zm8=" decodedAsBase64Data]]);
test([@"foo".encodedAsUtf8 isEqualToData:[@"Zm9v" decodedAsBase64Data]]);
test([@"foob".encodedAsUtf8 isEqualToData:[@"Zm9vYg==" decodedAsBase64Data]]);
test([@"fooba".encodedAsUtf8 isEqualToData:[@"Zm9vYmE=" decodedAsBase64Data]]);
test([@"foobar".encodedAsUtf8 isEqualToData:[@"Zm9vYmFy" decodedAsBase64Data]]);
}
-(void) testBase64Perturbed {
for (NSUInteger i = 0; i < 100; i++) {
uint32_t n = arc4random_uniform(10) + 10;
uint8_t data[n];
arc4random_buf(data, sizeof(data));
NSData* d = [NSData dataWithBytes:data length:sizeof(data)];
NSString* b = d.encodedAsBase64;
NSData* d2 = [b decodedAsBase64Data];
if (![d isEqualToData:d2]) {
XCTFail(@"%@",[d description]);
}
}
}
-(void) testToRegex {
testThrows(@"(".toRegularExpression);
NSRegularExpression* r = @"a+b".toRegularExpression;
@ -316,14 +70,6 @@
test([@"test" withPrefixRemovedElseNull:@"a"] == nil);
testThrows([@"test" withPrefixRemovedElseNull:nil]);
}
-(void) testToJson {
test([@{}.encodedAsJson isEqualToString:@"{}"]);
test([[@{@"a":@"b"} encodedAsJson] isEqualToString:@"{\"a\":\"b\"}"]);
test([[@{@"c":@5} encodedAsJson] isEqualToString:@"{\"c\":5}"]);
test([[(@{@"a":@5,@"b":@YES}) encodedAsJson] isEqualToString:@"{\"a\":5,\"b\":true}"]);
testThrows([@{@"ev": @"a+b".toRegularExpression} encodedAsJson]);
}
-(void) testFromJson {
test([[@"{}" decodedAsJsonIntoDictionary] isEqualToDictionary:@{}]);
test([[@"{\"a\":\"b\"}" decodedAsJsonIntoDictionary] isEqualToDictionary:@{@"a":@"b"}]);
@ -334,38 +80,6 @@
testThrows([@"}" decodedAsJsonIntoDictionary]);
testThrows([@"{{}" decodedAsJsonIntoDictionary]);
}
-(void) testRepresentedAsHexString {
test([[[NSData data] encodedAsHexString] isEqualToString:@""]);
test([increasingData(17).encodedAsHexString isEqualToString:@"000102030405060708090a0b0c0d0e0f10"]);
test([increasingDataFrom(256-16,16).encodedAsHexString isEqualToString:@"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"]);
}
-(void) testDecodedAsHexData {
test([[@"" decodedAsHexString] isEqualToData:[NSData data]]);
test([[@"000102030405060708090a0b0c0d0e0f10" decodedAsHexString] isEqualToData:increasingData(17)]);
test([[@"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" decodedAsHexString] isEqualToData:increasingDataFrom(256-16,16)]);
testThrows([@"gg" decodedAsHexString]);
testThrows([@"-1" decodedAsHexString]);
testThrows([@"a" decodedAsHexString]);
testThrows([@"-" decodedAsHexString]);
testThrows([@"0" decodedAsHexString]);
}
-(void) testHasUnsignedIntegerValue {
test((@0).hasUnsignedIntegerValue);
test((@1).hasUnsignedIntegerValue);
test((@0xFFFFFFFF).hasUnsignedIntegerValue);
test(@(pow(2, 31)).hasUnsignedIntegerValue);
test(!(@-1).hasUnsignedIntegerValue);
test(!(@0.5).hasUnsignedIntegerValue);
}
-(void) testHasUnsignedLongLongValue {
test((@0).hasUnsignedLongLongValue);
test((@1).hasUnsignedLongLongValue);
test((@0xFFFFFFFFFFFFFFFF).hasUnsignedLongLongValue);
test(@(pow(2, 63)).hasUnsignedLongLongValue);
test(!@(pow(2, 64)).hasUnsignedLongLongValue);
test(!(@-1).hasUnsignedLongLongValue);
test(!(@0.5).hasUnsignedLongLongValue);
}
-(void) testHasLongLongValue {
test((@0).hasLongLongValue);
test((@1).hasLongLongValue);