@tbvjaos510/react-native-paste-input 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/.circleci/config.yml +130 -0
  2. package/LICENSE +21 -0
  3. package/README.md +73 -0
  4. package/android/.project +17 -0
  5. package/android/.settings/org.eclipse.buildship.core.prefs +13 -0
  6. package/android/build.gradle +94 -0
  7. package/android/generated/java/com/facebook/react/viewmanagers/PasteTextInputManagerDelegate.java +236 -0
  8. package/android/generated/java/com/facebook/react/viewmanagers/PasteTextInputManagerInterface.java +84 -0
  9. package/android/generated/jni/CMakeLists.txt +36 -0
  10. package/android/generated/jni/PasteTextInputSpecs-generated.cpp +27 -0
  11. package/android/generated/jni/PasteTextInputSpecs.h +28 -0
  12. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/ComponentDescriptors.cpp +22 -0
  13. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/ComponentDescriptors.h +166 -0
  14. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/EventEmitters.cpp +183 -0
  15. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/EventEmitters.h +148 -0
  16. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/PasteTextInputSpecsJSI-generated.cpp +17 -0
  17. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/PasteTextInputSpecsJSI.h +19 -0
  18. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/Props.cpp +640 -0
  19. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/Props.h +144 -0
  20. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/ShadowNodes.cpp +247 -0
  21. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/ShadowNodes.h +95 -0
  22. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/States.cpp +14 -0
  23. package/android/generated/jni/react/renderer/components/PasteTextInputSpecs/States.h +19 -0
  24. package/android/gradle.properties +6 -0
  25. package/android/src/main/java/com/mattermost/pasteinputtext/IPasteInputListener.kt +8 -0
  26. package/android/src/main/java/com/mattermost/pasteinputtext/PasteInputActionCallback.kt +72 -0
  27. package/android/src/main/java/com/mattermost/pasteinputtext/PasteInputEditText.kt +60 -0
  28. package/android/src/main/java/com/mattermost/pasteinputtext/PasteInputFileFromUrl.kt +50 -0
  29. package/android/src/main/java/com/mattermost/pasteinputtext/PasteInputListener.kt +84 -0
  30. package/android/src/main/java/com/mattermost/pasteinputtext/PasteTextInputManager.kt +72 -0
  31. package/android/src/main/java/com/mattermost/pasteinputtext/PasteTextInputPackage.kt +14 -0
  32. package/android/src/main/java/com/mattermost/pasteinputtext/PasteTextInputPasteEvent.java +41 -0
  33. package/android/src/main/java/com/mattermost/pasteinputtext/RealPathUtil.kt +174 -0
  34. package/ios/NSData+MimeType.h +20 -0
  35. package/ios/NSData+MimeType.m +59 -0
  36. package/ios/PasteInput-Bridging-Header.h +1 -0
  37. package/ios/PasteInput.xcodeproj/project.pbxproj +319 -0
  38. package/ios/PasteInputTextView.h +20 -0
  39. package/ios/PasteInputTextView.m +68 -0
  40. package/ios/PasteInputView.h +18 -0
  41. package/ios/PasteInputView.m +96 -0
  42. package/ios/PasteTextInput.h +13 -0
  43. package/ios/PasteTextInput.mm +726 -0
  44. package/ios/PasteTextInputManager.mm +171 -0
  45. package/ios/Swime/MimeType.h +70 -0
  46. package/ios/Swime/MimeType.m +701 -0
  47. package/ios/Swime/Swime.h +14 -0
  48. package/ios/Swime/Swime.m +28 -0
  49. package/ios/Swime/SwimeProxy.h +18 -0
  50. package/ios/Swime/SwimeProxy.m +66 -0
  51. package/ios/Swime/SwimeUtils.h +12 -0
  52. package/ios/Swime/SwimeUtils.m +23 -0
  53. package/ios/UIImage+ImageEffects.h +112 -0
  54. package/ios/UIImage+ImageEffects.m +310 -0
  55. package/ios/UIImage+vImageScaling.h +16 -0
  56. package/ios/UIImage+vImageScaling.m +48 -0
  57. package/ios/UIPasteboard+GetImageInfo.h +19 -0
  58. package/ios/UIPasteboard+GetImageInfo.m +98 -0
  59. package/ios/generated/PasteTextInputSpecs/ComponentDescriptors.cpp +22 -0
  60. package/ios/generated/PasteTextInputSpecs/ComponentDescriptors.h +42 -0
  61. package/ios/generated/PasteTextInputSpecs/EventEmitters.cpp +41 -0
  62. package/ios/generated/PasteTextInputSpecs/EventEmitters.h +37 -0
  63. package/ios/generated/PasteTextInputSpecs/PasteTextInputSpecs-generated.mm +16 -0
  64. package/ios/generated/PasteTextInputSpecs/PasteTextInputSpecs.h +38 -0
  65. package/ios/generated/PasteTextInputSpecs/Props.cpp +142 -0
  66. package/ios/generated/PasteTextInputSpecs/Props.h +81 -0
  67. package/ios/generated/PasteTextInputSpecs/RCTComponentViewHelpers.h +106 -0
  68. package/ios/generated/PasteTextInputSpecs/ShadowNodes.cpp +127 -0
  69. package/ios/generated/PasteTextInputSpecs/ShadowNodes.h +85 -0
  70. package/ios/generated/PasteTextInputSpecs/States.cpp +16 -0
  71. package/ios/generated/PasteTextInputSpecs/States.h +53 -0
  72. package/ios/generated/PasteTextInputSpecsJSI-generated.cpp +17 -0
  73. package/ios/generated/PasteTextInputSpecsJSI.h +19 -0
  74. package/lib/commonjs/PasteTextInput.js +446 -0
  75. package/lib/commonjs/PasteTextInput.js.map +1 -0
  76. package/lib/commonjs/PasteTextInputNativeComponent.ts +277 -0
  77. package/lib/commonjs/index.js +25 -0
  78. package/lib/commonjs/index.js.map +1 -0
  79. package/lib/commonjs/module.d.js +2 -0
  80. package/lib/commonjs/module.d.js.map +1 -0
  81. package/lib/commonjs/package.json +1 -0
  82. package/lib/commonjs/types.js +6 -0
  83. package/lib/commonjs/types.js.map +1 -0
  84. package/lib/module/PasteTextInput.js +440 -0
  85. package/lib/module/PasteTextInput.js.map +1 -0
  86. package/lib/module/PasteTextInputNativeComponent.ts +277 -0
  87. package/lib/module/index.js +9 -0
  88. package/lib/module/index.js.map +1 -0
  89. package/lib/module/module.d.js +2 -0
  90. package/lib/module/module.d.js.map +1 -0
  91. package/lib/module/types.js +4 -0
  92. package/lib/module/types.js.map +1 -0
  93. package/lib/typescript/src/PasteTextInput.d.ts +5 -0
  94. package/lib/typescript/src/PasteTextInput.d.ts.map +1 -0
  95. package/lib/typescript/src/PasteTextInputNativeComponent.d.ts +168 -0
  96. package/lib/typescript/src/PasteTextInputNativeComponent.d.ts.map +1 -0
  97. package/lib/typescript/src/index.d.ts +6 -0
  98. package/lib/typescript/src/index.d.ts.map +1 -0
  99. package/lib/typescript/src/types.d.ts +56 -0
  100. package/lib/typescript/src/types.d.ts.map +1 -0
  101. package/package.json +140 -0
  102. package/react-native-paste-input.podspec +20 -0
  103. package/react-native.config.js +13 -0
  104. package/src/PasteTextInput.tsx +615 -0
  105. package/src/PasteTextInputNativeComponent.ts +277 -0
  106. package/src/index.ts +13 -0
  107. package/src/module.d.ts +4 -0
  108. package/src/types.ts +71 -0
@@ -0,0 +1,701 @@
1
+ #import "MimeType.h"
2
+
3
+ @implementation MimeType
4
+
5
+ + (NSArray<MimeType *> *)all {
6
+ return @[
7
+ [[MimeType alloc] initWithMime:@"image/jpeg"
8
+ ext:@"jpg"
9
+ type:FileTypeJPG
10
+ bytesCount:3
11
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
12
+ NSUInteger length = bytes.length;
13
+ if (length < 3) {
14
+ return NO;
15
+ }
16
+ const uint8_t *data = bytes.bytes;
17
+ return data[0] == 0xFF && data[1] == 0xD8 && data[2] == 0xFF;
18
+ }],
19
+ [[MimeType alloc] initWithMime:@"image/png"
20
+ ext:@"png"
21
+ type:FileTypePNG
22
+ bytesCount:4
23
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
24
+ NSUInteger length = bytes.length;
25
+ if (length < 4) {
26
+ return NO;
27
+ }
28
+ const uint8_t *data = bytes.bytes;
29
+ return data[0] == 0x89 && data[1] == 0x50 && data[2] == 0x4E && data[3] == 0x47;
30
+ }],
31
+ [[MimeType alloc] initWithMime:@"image/gif"
32
+ ext:@"gif"
33
+ type:FileTypeGIF
34
+ bytesCount:3
35
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
36
+ NSUInteger length = bytes.length;
37
+ if (length < 3) {
38
+ return NO;
39
+ }
40
+ const uint8_t *data = bytes.bytes;
41
+ return data[0] == 0x47 && data[1] == 0x49 && data[2] == 0x46;
42
+ }],
43
+ [[MimeType alloc] initWithMime:@"image/webp"
44
+ ext:@"webp"
45
+ type:FileTypeWEBP
46
+ bytesCount:12
47
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
48
+ NSUInteger length = bytes.length;
49
+ if (length < 12) {
50
+ return NO;
51
+ }
52
+ const uint8_t *data = bytes.bytes;
53
+ return data[8] == 0x57 && data[9] == 0x45 && data[10] == 0x42 && data[11] == 0x50;
54
+ }],
55
+ [[MimeType alloc] initWithMime:@"image/flif"
56
+ ext:@"flif"
57
+ type:FileTypeFLIF
58
+ bytesCount:4
59
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
60
+ NSUInteger length = bytes.length;
61
+ if (length < 4) {
62
+ return NO;
63
+ }
64
+ const uint8_t *data = bytes.bytes;
65
+ return data[0] == 0x46 && data[1] == 0x4C && data[2] == 0x49 && data[3] == 0x46;
66
+ }],
67
+ [[MimeType alloc] initWithMime:@"image/x-canon-cr2"
68
+ ext:@"cr2"
69
+ type:FileTypeCR2
70
+ bytesCount:10
71
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
72
+ NSUInteger length = bytes.length;
73
+ if (length < 10) {
74
+ return NO;
75
+ }
76
+ const uint8_t *data = bytes.bytes;
77
+ return ((data[0] == 0x49 && data[1] == 0x49 && data[2] == 0x2A && data[3] == 0x00) ||
78
+ (data[0] == 0x4D && data[1] == 0x4D && data[2] == 0x00 && data[3] == 0x2A)) &&
79
+ (data[8] == 0x43 && data[9] == 0x52);
80
+ }],
81
+ [[MimeType alloc] initWithMime:@"image/tiff"
82
+ ext:@"tif"
83
+ type:FileTypeTIF
84
+ bytesCount:4
85
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
86
+ NSUInteger length = bytes.length;
87
+ if (length < 4) {
88
+ return NO;
89
+ }
90
+ const uint8_t *data = bytes.bytes;
91
+ return (data[0] == 0x49 && data[1] == 0x49 && data[2] == 0x2A && data[3] == 0x00) ||
92
+ (data[0] == 0x4D && data[1] == 0x4D && data[2] == 0x00 && data[3] == 0x2A);
93
+ }],
94
+ [[MimeType alloc] initWithMime:@"image/bmp"
95
+ ext:@"bmp"
96
+ type:FileTypeBMP
97
+ bytesCount:2
98
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
99
+ NSUInteger length = bytes.length;
100
+ if (length < 2) {
101
+ return NO;
102
+ }
103
+ const uint8_t *data = bytes.bytes;
104
+ return data[0] == 0x42 && data[1] == 0x4D;
105
+ }],
106
+ [[MimeType alloc] initWithMime:@"image/vnd.ms-photo"
107
+ ext:@"jxr"
108
+ type:FileTypeJXR
109
+ bytesCount:3
110
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
111
+ NSUInteger length = bytes.length;
112
+ if (length < 3) {
113
+ return NO;
114
+ }
115
+ const uint8_t *data = bytes.bytes;
116
+ return data[0] == 0x49 && data[1] == 0x49 && data[2] == 0xBC;
117
+ }],
118
+ [[MimeType alloc] initWithMime:@"image/vnd.adobe.photoshop"
119
+ ext:@"psd"
120
+ type:FileTypePSD
121
+ bytesCount:4
122
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
123
+ NSUInteger length = bytes.length;
124
+ if (length < 4) {
125
+ return NO;
126
+ }
127
+ const uint8_t *data = bytes.bytes;
128
+ return data[0] == 0x38 && data[1] == 0x42 && data[2] == 0x50 && data[3] == 0x53;
129
+ }],
130
+ [[MimeType alloc] initWithMime:@"video/x-m4v"
131
+ ext:@"m4v"
132
+ type:FileTypeM4V
133
+ bytesCount:11
134
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
135
+ NSData *expectedData = [NSData dataWithBytes:(const uint8_t[]){0x00, 0x00, 0x00, 0x1C, 0x66, 0x74, 0x79, 0x70, 0x4D, 0x34, 0x56} length:11];
136
+ return [bytes isEqualToData:expectedData];
137
+ }],
138
+ [[MimeType alloc] initWithMime:@"audio/midi"
139
+ ext:@"mid"
140
+ type:FileTypeMID
141
+ bytesCount:4
142
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
143
+ NSData *expectedData = [NSData dataWithBytes:(const uint8_t[]){0x4D, 0x54, 0x68, 0x64} length:4];
144
+ return [bytes isEqualToData:expectedData];
145
+ }],
146
+ [[MimeType alloc] initWithMime:@"video/x-matroska"
147
+ ext:@"mkv"
148
+ type:FileTypeMKV
149
+ bytesCount:4
150
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
151
+ if (![bytes isEqualToData:[NSData dataWithBytes:(const uint8_t[]){0x1A, 0x45, 0xDF, 0xA3} length:4]]) {
152
+ return NO;
153
+ }
154
+
155
+ NSData *data = [swime readBytesWithCount:4100];
156
+ NSData *subData = [data subdataWithRange:NSMakeRange(4, 4096)];
157
+ NSArray *_bytes = [NSArray arrayWithArray:[subData bytes]];
158
+
159
+ NSInteger idPos = -1;
160
+ for (NSInteger i = 0; i < _bytes.count - 1; i++) {
161
+ if ([_bytes[i] isEqual:@(0x42)] && [_bytes[i + 1] isEqual:@(0x82)]) {
162
+ idPos = i;
163
+ break;
164
+ }
165
+ }
166
+
167
+ if (idPos == -1) {
168
+ return NO;
169
+ }
170
+
171
+ NSInteger docTypePos = idPos + 3;
172
+ BOOL (^findDocType)(NSString *) = ^BOOL(NSString *type) {
173
+ for (NSInteger i = 0; i < type.length; i++) {
174
+ unichar expectedChar = [type characterAtIndex:i];
175
+ if (docTypePos + i >= _bytes.count) {
176
+ return NO;
177
+ }
178
+
179
+ UInt8 byteValue = [_bytes[docTypePos + i] unsignedCharValue];
180
+ if (byteValue != (UInt8)expectedChar) {
181
+ return NO;
182
+ }
183
+ }
184
+
185
+ return YES;
186
+ };
187
+
188
+ return findDocType(@"matroska");
189
+ }],
190
+ [[MimeType alloc] initWithMime:@"video/webm"
191
+ ext:@"webm"
192
+ type:FileTypeWEBM
193
+ bytesCount:4
194
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
195
+ if (![bytes isEqualToData:[NSData dataWithBytes:(const uint8_t[]){0x1A, 0x45, 0xDF, 0xA3} length:4]]) {
196
+ return NO;
197
+ }
198
+
199
+ NSData *data = [swime readBytesWithCount:4100];
200
+ NSData *subData = [data subdataWithRange:NSMakeRange(4, 4096)];
201
+ NSArray *_bytes = [NSArray arrayWithArray:[subData bytes]];
202
+
203
+ NSInteger idPos = -1;
204
+ for (NSInteger i = 0; i < _bytes.count - 1; i++) {
205
+ if ([_bytes[i] isEqual:@(0x42)] && [_bytes[i + 1] isEqual:@(0x82)]) {
206
+ idPos = i;
207
+ break;
208
+ }
209
+ }
210
+
211
+ if (idPos == -1) {
212
+ return NO;
213
+ }
214
+
215
+ NSInteger docTypePos = idPos + 3;
216
+ BOOL (^findDocType)(NSString *) = ^BOOL(NSString *type) {
217
+ for (NSInteger i = 0; i < type.length; i++) {
218
+ unichar expectedChar = [type characterAtIndex:i];
219
+ if (docTypePos + i >= _bytes.count) {
220
+ return NO;
221
+ }
222
+
223
+ UInt8 byteValue = [_bytes[docTypePos + i] unsignedCharValue];
224
+ if (byteValue != (UInt8)expectedChar) {
225
+ return NO;
226
+ }
227
+ }
228
+ return YES;
229
+ };
230
+
231
+ return findDocType(@"webm");
232
+ }],
233
+ [[MimeType alloc] initWithMime:@"video/quicktime"
234
+ ext:@"mov"
235
+ type:FileTypeMOV
236
+ bytesCount:8
237
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
238
+ NSData *expectedData = [NSData dataWithBytes:(const uint8_t[]){0x00, 0x00, 0x00, 0x14, 0x66, 0x74, 0x79, 0x70} length:8];
239
+ return [bytes isEqualToData:expectedData];
240
+ }],
241
+ [[MimeType alloc] initWithMime:@"video/x-msvideo"
242
+ ext:@"avi"
243
+ type:FileTypeAVI
244
+ bytesCount:11
245
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
246
+ NSData *expectedData1 = [NSData dataWithBytes:(const uint8_t[]){0x52, 0x49, 0x46, 0x46} length:4];
247
+ NSData *expectedData2 = [NSData dataWithBytes:(const uint8_t[]){0x41, 0x56, 0x49} length:3];
248
+ return [[bytes subdataWithRange:NSMakeRange(0, 4)] isEqualToData:expectedData1] && [[bytes subdataWithRange:NSMakeRange(8, 3)] isEqualToData:expectedData2];
249
+ }],
250
+ [[MimeType alloc] initWithMime:@"video/x-ms-wmv"
251
+ ext:@"wmv"
252
+ type:FileTypeWMV
253
+ bytesCount:10
254
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
255
+ NSData *expectedData = [NSData dataWithBytes:(const uint8_t[]){0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9} length:10];
256
+ return [bytes isEqualToData:expectedData];
257
+ }],
258
+ [[MimeType alloc] initWithMime:@"video/mpeg"
259
+ ext:@"mpg"
260
+ type:FileTypeMPG
261
+ bytesCount:4
262
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
263
+ if (![[bytes subdataWithRange:NSMakeRange(0, 3)] isEqualToData:[NSData dataWithBytes:(const uint8_t[]){0x00, 0x00, 0x01} length:3]]) {
264
+ return NO;
265
+ }
266
+
267
+ if (bytes.length >= 4) {
268
+ uint8_t fourthByte;
269
+ [bytes getBytes:&fourthByte range:NSMakeRange(3, 1)];
270
+ NSString *hexCode = [NSString stringWithFormat:@"%02X", fourthByte];
271
+ return hexCode.length > 0 && [hexCode characterAtIndex:0] == 'B';
272
+ }
273
+ return NO; // Handle edge case if bytes length is less than 4
274
+ }],
275
+ [[MimeType alloc] initWithMime:@"audio/mpeg"
276
+ ext:@"mp3"
277
+ type:FileTypeMP3
278
+ bytesCount:3
279
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
280
+ NSData *data = [bytes subdataWithRange:NSMakeRange(0, 3)];
281
+ NSData *pattern1 = [NSData dataWithBytes:(const uint8_t[]){0x49, 0x44, 0x33} length:3];
282
+ NSData *pattern2 = [NSData dataWithBytes:(const uint8_t[]){0xFF, 0xFB} length:2];
283
+ return [data isEqualToData:pattern1] || [data isEqualToData:pattern2];
284
+ }],
285
+ [[MimeType alloc] initWithMime:@"audio/m4a"
286
+ ext:@"m4a"
287
+ type:FileTypeM4A
288
+ bytesCount:11
289
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
290
+ NSData *data1 = [bytes subdataWithRange:NSMakeRange(0, 4)];
291
+ NSData *data2 = [bytes subdataWithRange:NSMakeRange(4, 7)];
292
+ NSData *pattern1 = [NSData dataWithBytes:(const uint8_t[]){0x4D, 0x34, 0x41, 0x20} length:4];
293
+ NSData *pattern2 = [NSData dataWithBytes:(const uint8_t[]){0x66, 0x74, 0x79, 0x70, 0x4D, 0x34, 0x41} length:7];
294
+ return [data1 isEqualToData:pattern1] || [data2 isEqualToData:pattern2];
295
+ }],
296
+ [[MimeType alloc] initWithMime:@"audio/opus"
297
+ ext:@"opus"
298
+ type:FileTypeOPUS
299
+ bytesCount:36
300
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
301
+ NSData *data = [bytes subdataWithRange:NSMakeRange(28, 8)];
302
+ NSData *pattern = [NSData dataWithBytes:(const uint8_t[]){0x4F, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64} length:8];
303
+ return [data isEqualToData:pattern];
304
+ }],
305
+ [[MimeType alloc] initWithMime:@"audio/ogg"
306
+ ext:@"ogg"
307
+ type:FileTypeOGG
308
+ bytesCount:4
309
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
310
+ NSData *data = [bytes subdataWithRange:NSMakeRange(0, 4)];
311
+ NSData *pattern = [NSData dataWithBytes:(const uint8_t[]){0x4F, 0x67, 0x67, 0x53} length:4];
312
+ return [data isEqualToData:pattern];
313
+ }],
314
+ [[MimeType alloc] initWithMime:@"audio/x-flac"
315
+ ext:@"flac"
316
+ type:FileTypeFLAC
317
+ bytesCount:4
318
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
319
+ NSData *data = [bytes subdataWithRange:NSMakeRange(0, 4)];
320
+ NSData *pattern = [NSData dataWithBytes:(const uint8_t[]){0x66, 0x4C, 0x61, 0x43} length:4];
321
+ return [data isEqualToData:pattern];
322
+ }],
323
+ [[MimeType alloc] initWithMime:@"audio/x-wav"
324
+ ext:@"wav"
325
+ type:FileTypeWAV
326
+ bytesCount:12
327
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
328
+ NSData *data1 = [bytes subdataWithRange:NSMakeRange(0, 4)];
329
+ NSData *data2 = [bytes subdataWithRange:NSMakeRange(8, 4)];
330
+ NSData *pattern1 = [NSData dataWithBytes:(const uint8_t[]){0x52, 0x49, 0x46, 0x46} length:4];
331
+ NSData *pattern2 = [NSData dataWithBytes:(const uint8_t[]){0x57, 0x41, 0x56, 0x45} length:4];
332
+ return [data1 isEqualToData:pattern1] && [data2 isEqualToData:pattern2];
333
+ }],
334
+ [[MimeType alloc] initWithMime:@"audio/amr"
335
+ ext:@"amr"
336
+ type:FileTypeAMR
337
+ bytesCount:6
338
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
339
+ NSData *data = [bytes subdataWithRange:NSMakeRange(0, 6)];
340
+ NSData *pattern = [NSData dataWithBytes:(const uint8_t[]){0x23, 0x21, 0x41, 0x4D, 0x52, 0x0A} length:6];
341
+ return [data isEqualToData:pattern];
342
+ }],
343
+ [[MimeType alloc] initWithMime:@"application/pdf"
344
+ ext:@"pdf"
345
+ type:FileTypePdf
346
+ bytesCount:4
347
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
348
+ if (bytes.length < 4) {
349
+ return NO;
350
+ }
351
+
352
+ const uint8_t *dataBytes = bytes.bytes;
353
+ return (dataBytes[0] == 0x25 &&
354
+ dataBytes[1] == 0x50 &&
355
+ dataBytes[2] == 0x44 &&
356
+ dataBytes[3] == 0x46);
357
+ }],
358
+ [[MimeType alloc] initWithMime:@"application/x-msdownload"
359
+ ext:@"exe"
360
+ type:FileTypeExe
361
+ bytesCount:2
362
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
363
+ if (bytes.length < 2) {
364
+ return NO;
365
+ }
366
+
367
+ const uint8_t *dataBytes = bytes.bytes;
368
+ return (dataBytes[0] == 0x4D && dataBytes[1] == 0x5A);
369
+ }],
370
+ [[MimeType alloc] initWithMime:@"application/x-shockwave-flash"
371
+ ext:@"swf"
372
+ type:FileTypeSwf
373
+ bytesCount:5
374
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
375
+ if (bytes.length < 4) {
376
+ return NO;
377
+ }
378
+
379
+ const uint8_t *dataBytes = bytes.bytes;
380
+ return (dataBytes[0] == 0x43 &&
381
+ dataBytes[1] == 0x46 &&
382
+ dataBytes[2] == 0x57 &&
383
+ dataBytes[3] == 0x53);
384
+ }],
385
+ [[MimeType alloc] initWithMime:@"application/rtf"
386
+ ext:@"rtf"
387
+ type:FileTypeRtf
388
+ bytesCount:5
389
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
390
+ if (bytes.length < 5) {
391
+ return NO;
392
+ }
393
+
394
+ const uint8_t *dataBytes = bytes.bytes;
395
+ return (dataBytes[0] == 0x7B &&
396
+ dataBytes[1] == 0x5C &&
397
+ dataBytes[2] == 0x72 &&
398
+ dataBytes[3] == 0x74 &&
399
+ dataBytes[4] == 0x66);
400
+ }],
401
+ [[MimeType alloc] initWithMime:@"application/font-woff"
402
+ ext:@"woff"
403
+ type:FileTypeWoff
404
+ bytesCount:8
405
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
406
+ if (bytes.length < 8) {
407
+ return NO;
408
+ }
409
+
410
+ const uint8_t *dataBytes = bytes.bytes;
411
+ BOOL isMagicNumberValid = (dataBytes[0] == 0x77 &&
412
+ dataBytes[1] == 0x4F &&
413
+ dataBytes[2] == 0x46 &&
414
+ dataBytes[3] == 0x46);
415
+
416
+ BOOL isFontVersionValid = ((dataBytes[4] == 0x00 &&
417
+ dataBytes[5] == 0x01 &&
418
+ dataBytes[6] == 0x00 &&
419
+ dataBytes[7] == 0x00) ||
420
+ (dataBytes[4] == 0x4F &&
421
+ dataBytes[5] == 0x54 &&
422
+ dataBytes[6] == 0x54 &&
423
+ dataBytes[7] == 0x4F));
424
+
425
+ return (isMagicNumberValid && isFontVersionValid);
426
+ }],
427
+ [[MimeType alloc] initWithMime:@"application/font-woff"
428
+ ext:@"woff2"
429
+ type:FileTypeWoff2
430
+ bytesCount:8
431
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
432
+ if (bytes.length < 8) {
433
+ return NO;
434
+ }
435
+
436
+ const uint8_t *dataBytes = bytes.bytes;
437
+ BOOL isMagicNumberValid = (dataBytes[0] == 0x77 &&
438
+ dataBytes[1] == 0x4F &&
439
+ dataBytes[2] == 0x46 &&
440
+ dataBytes[3] == 0x32);
441
+ BOOL isFontVersionValid = ((dataBytes[4] == 0x00 &&
442
+ dataBytes[5] == 0x01 &&
443
+ dataBytes[6] == 0x00 &&
444
+ dataBytes[7] == 0x00) ||
445
+ (dataBytes[4] == 0x4F &&
446
+ dataBytes[5] == 0x54 &&
447
+ dataBytes[6] == 0x54 &&
448
+ dataBytes[7] == 0x4F));
449
+
450
+ return (isMagicNumberValid && isFontVersionValid);
451
+ }],
452
+ [[MimeType alloc] initWithMime:@"application/octet-stream"
453
+ ext:@"eot"
454
+ type:FileTypeEot
455
+ bytesCount:36
456
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
457
+ if (bytes.length < 36) {
458
+ return NO;
459
+ }
460
+
461
+ const uint8_t *dataBytes = bytes.bytes;
462
+ BOOL isMagicNumberValid = (dataBytes[34] == 0x4C && dataBytes[35] == 0x50);
463
+ BOOL isFontVersionValid = ((dataBytes[8] == 0x00 && dataBytes[9] == 0x00 && dataBytes[10] == 0x01) ||
464
+ (dataBytes[8] == 0x01 && dataBytes[9] == 0x00 && dataBytes[10] == 0x02) ||
465
+ (dataBytes[8] == 0x02 && dataBytes[9] == 0x00 && dataBytes[10] == 0x02));
466
+
467
+ return (isMagicNumberValid && isFontVersionValid);
468
+ }],
469
+ [[MimeType alloc] initWithMime:@"application/font-sfnt"
470
+ ext:@"ttf"
471
+ type:FileTypeTtf
472
+ bytesCount:5
473
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
474
+ if (bytes.length < 5) {
475
+ return NO;
476
+ }
477
+
478
+ const uint8_t *dataBytes = bytes.bytes;
479
+ return (dataBytes[0] == 0x00 &&
480
+ dataBytes[1] == 0x01 &&
481
+ dataBytes[2] == 0x00 &&
482
+ dataBytes[3] == 0x00 &&
483
+ dataBytes[4] == 0x00);
484
+ }],
485
+ [[MimeType alloc] initWithMime:@"application/font-sfnt"
486
+ ext:@"otf"
487
+ type:FileTypeOtf
488
+ bytesCount:5
489
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
490
+ if (bytes.length < 5) {
491
+ return NO;
492
+ }
493
+
494
+ const uint8_t *dataBytes = bytes.bytes;
495
+ return (dataBytes[0] == 0x4F &&
496
+ dataBytes[1] == 0x54 &&
497
+ dataBytes[2] == 0x54 &&
498
+ dataBytes[3] == 0x4F &&
499
+ dataBytes[4] == 0x00);
500
+ }],
501
+ [[MimeType alloc] initWithMime:@"image/x-icon"
502
+ ext:@"ico"
503
+ type:FileTypeIco
504
+ bytesCount:4
505
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
506
+ if (bytes.length < 4) {
507
+ return NO;
508
+ }
509
+
510
+ const uint8_t *dataBytes = bytes.bytes;
511
+ return (dataBytes[0] == 0x00 &&
512
+ dataBytes[1] == 0x00 &&
513
+ dataBytes[2] == 0x01 &&
514
+ dataBytes[3] == 0x00);
515
+ }],
516
+ [[MimeType alloc] initWithMime:@"video/x-flv"
517
+ ext:@"flv"
518
+ type:FileTypeFlv
519
+ bytesCount:4
520
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
521
+ if (bytes.length < 4) {
522
+ return NO;
523
+ }
524
+
525
+ const uint8_t *dataBytes = bytes.bytes;
526
+ return (dataBytes[0] == 0x46 &&
527
+ dataBytes[1] == 0x4C &&
528
+ dataBytes[2] == 0x56 &&
529
+ dataBytes[3] == 0x01);
530
+ }],
531
+ [[MimeType alloc] initWithMime:@"application/postscript"
532
+ ext:@"ps"
533
+ type:FileTypePs
534
+ bytesCount:2
535
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
536
+ if (bytes.length < 2) {
537
+ return NO;
538
+ }
539
+
540
+ const uint8_t *dataBytes = bytes.bytes;
541
+ return (dataBytes[0] == 0x25 &&
542
+ dataBytes[2] == 0x21);
543
+ }],
544
+ [[MimeType alloc] initWithMime:@"application/x-xz"
545
+ ext:@"xz"
546
+ type:FileTypeXz
547
+ bytesCount:6
548
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
549
+ if (bytes.length < 6) {
550
+ return NO;
551
+ }
552
+
553
+ const uint8_t *dataBytes = bytes.bytes;
554
+ return (dataBytes[0] == 0xFD &&
555
+ dataBytes[1] == 0x37 &&
556
+ dataBytes[2] == 0x7A &&
557
+ dataBytes[3] == 0x58 &&
558
+ dataBytes[4] == 0x5A &&
559
+ dataBytes[5] == 0x00);
560
+ }],
561
+ [[MimeType alloc] initWithMime:@"application/x-sqlite3"
562
+ ext:@"sqlite"
563
+ type:FileTypeSqlite
564
+ bytesCount:4
565
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
566
+ if (bytes.length < 4) {
567
+ return NO;
568
+ }
569
+
570
+ const uint8_t *dataBytes = bytes.bytes;
571
+ return (dataBytes[0] == 0x53 &&
572
+ dataBytes[1] == 0x51 &&
573
+ dataBytes[2] == 0x4C &&
574
+ dataBytes[3] == 0x69);
575
+ }],
576
+ [[MimeType alloc] initWithMime:@"application/x-nintendo-nes-rom"
577
+ ext:@"nes"
578
+ type:FileTypeNes
579
+ bytesCount:4
580
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
581
+ if (bytes.length < 4) {
582
+ return NO;
583
+ }
584
+
585
+ const uint8_t *dataBytes = bytes.bytes;
586
+ return (dataBytes[0] == 0x4E &&
587
+ dataBytes[1] == 0x45 &&
588
+ dataBytes[2] == 0x53 &&
589
+ dataBytes[3] == 0x1A);
590
+ }],
591
+ [[MimeType alloc] initWithMime:@"application/x-google-chrome-extension"
592
+ ext:@"crx"
593
+ type:FileTypeCrx
594
+ bytesCount:4
595
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
596
+ NSData *data = [bytes subdataWithRange:NSMakeRange(0, 4)];
597
+ NSData *expected = [NSData dataWithBytes:(const uint8_t[]){0x43, 0x72, 0x32, 0x34} length:4];
598
+ return [data isEqualToData:expected];
599
+ }],
600
+ [[MimeType alloc] initWithMime:@"application/vnd.ms-cab-compressed"
601
+ ext:@"cab"
602
+ type:FileTypeCab
603
+ bytesCount:4
604
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
605
+ NSData *data = [bytes subdataWithRange:NSMakeRange(0, 4)];
606
+ NSData *expected1 = [NSData dataWithBytes:(const uint8_t[]){0x4D, 0x53, 0x43, 0x46} length:4];
607
+ NSData *expected2 = [NSData dataWithBytes:(const uint8_t[]){0x49, 0x53, 0x63, 0x28} length:4];
608
+ return [data isEqualToData:expected1] || [data isEqualToData:expected2];
609
+ }],
610
+ [[MimeType alloc] initWithMime:@"application/x-deb"
611
+ ext:@"deb"
612
+ type:FileTypeDeb
613
+ bytesCount:21
614
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
615
+ NSData *data = [bytes subdataWithRange:NSMakeRange(0, 21)];
616
+ NSData *expected = [NSData dataWithBytes:(const uint8_t[]){
617
+ 0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E, 0x0A, 0x64, 0x65, 0x62, 0x69,
618
+ 0x61, 0x6E, 0x2D, 0x62, 0x69, 0x6E, 0x61, 0x72, 0x79
619
+ } length:21];
620
+ return [data isEqualToData:expected];
621
+ }],
622
+ [[MimeType alloc] initWithMime:@"application/x-unix-archive"
623
+ ext:@"ar"
624
+ type:FileTypeAr
625
+ bytesCount:7
626
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
627
+ NSData *data = [bytes subdataWithRange:NSMakeRange(0, 7)];
628
+ NSData *expected = [NSData dataWithBytes:(const uint8_t[]){0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E} length:7];
629
+ return [data isEqualToData:expected];
630
+ }],
631
+ [[MimeType alloc] initWithMime:@"application/x-rpm"
632
+ ext:@"rpm"
633
+ type:FileTypeRpm
634
+ bytesCount:4
635
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
636
+ NSData *data = [bytes subdataWithRange:NSMakeRange(0, 4)];
637
+ NSData *expected = [NSData dataWithBytes:(const uint8_t[]){0xED, 0xAB, 0xEE, 0xDB} length:4];
638
+ return [data isEqualToData:expected];
639
+ }],
640
+ [[MimeType alloc] initWithMime:@"application/x-compress"
641
+ ext:@"Z"
642
+ type:FileTypeZ
643
+ bytesCount:2
644
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
645
+ NSData *data = [bytes subdataWithRange:NSMakeRange(0, 2)];
646
+ NSData *expected1 = [NSData dataWithBytes:(const uint8_t[]){0x1F, 0xA0} length:2];
647
+ NSData *expected2 = [NSData dataWithBytes:(const uint8_t[]){0x1F, 0x9D} length:2];
648
+ return [data isEqualToData:expected1] || [data isEqualToData:expected2];
649
+ }],
650
+ [[MimeType alloc] initWithMime:@"application/x-lzip"
651
+ ext:@"lz"
652
+ type:FileTypeLz
653
+ bytesCount:4
654
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
655
+ NSData *data = [bytes subdataWithRange:NSMakeRange(0, 4)];
656
+ NSData *expected = [NSData dataWithBytes:(const uint8_t[]){0x4C, 0x5A, 0x49, 0x50} length:4];
657
+ return [data isEqualToData:expected];
658
+ }],
659
+ [[MimeType alloc] initWithMime:@"application/x-msi"
660
+ ext:@"msi"
661
+ type:FileTypeMsi
662
+ bytesCount:8
663
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
664
+ NSData *data = [bytes subdataWithRange:NSMakeRange(0, 8)];
665
+ NSData *expected = [NSData dataWithBytes:(const uint8_t[]){0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1} length:8];
666
+ return [data isEqualToData:expected];
667
+ }],
668
+ [[MimeType alloc] initWithMime:@"application/mxf"
669
+ ext:@"mxf"
670
+ type:FileTypeMxf
671
+ bytesCount:14
672
+ matches:^BOOL(NSData *bytes, SwimeUtils *swime) {
673
+ NSData *data = [bytes subdataWithRange:NSMakeRange(0, 14)];
674
+ NSData *expected = [NSData dataWithBytes:(const uint8_t[]){0x06, 0x0E, 0x2B, 0x34, 0x02, 0x05, 0x01, 0x01, 0x0D, 0x01, 0x02, 0x01, 0x01, 0x02} length:14];
675
+ return [data isEqualToData:expected];
676
+ }]
677
+ ];
678
+ }
679
+
680
+ - (instancetype)initWithMime:(NSString *)mime
681
+ ext:(NSString *)ext
682
+ type:(FileType)type
683
+ bytesCount:(NSInteger)bytesCount
684
+ matches:(BOOL (^)(NSData *, SwimeUtils *))matches {
685
+ self = [super init];
686
+ if (self) {
687
+ _mime = mime;
688
+ _ext = ext;
689
+ _type = type;
690
+ _bytesCount = bytesCount;
691
+ _matches = [matches copy];
692
+ }
693
+ return self;
694
+ }
695
+
696
+ - (BOOL)matchesBytes:(NSData *)bytes swime:(SwimeUtils *)swime {
697
+ return bytes.length >= self.bytesCount && self.matches(bytes, swime);
698
+ }
699
+
700
+ @end
701
+