Skip to content

Commit cf30697

Browse files
authored
[blob] Migrate ExpoBlob to expo/expo fork
2 parents 82935a2 + df06281 commit cf30697

35 files changed

+727
-0
lines changed

apps/bare-expo/ios/Podfile.lock

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,8 @@ PODS:
424424
- ExpoModulesCore
425425
- ExpoBattery (9.1.4):
426426
- ExpoModulesCore
427+
- ExpoBlob (0.1.0):
428+
- ExpoModulesCore
427429
- ExpoBlur (14.1.4):
428430
- ExpoModulesCore
429431
- ExpoBrightness (13.1.4):
@@ -3671,6 +3673,7 @@ DEPENDENCIES:
36713673
- ExpoBackgroundFetch (from `../../../packages/expo-background-fetch/ios`)
36723674
- ExpoBackgroundTask (from `../../../packages/expo-background-task/ios`)
36733675
- ExpoBattery (from `../../../packages/expo-battery/ios`)
3676+
- ExpoBlob (from `../../../packages/expo-blob/ios`)
36743677
- ExpoBlur (from `../../../packages/expo-blur/ios`)
36753678
- ExpoBrightness (from `../../../packages/expo-brightness/ios`)
36763679
- ExpoCalendar (from `../../../packages/expo-calendar/ios`)
@@ -3907,6 +3910,9 @@ EXTERNAL SOURCES:
39073910
ExpoBattery:
39083911
inhibit_warnings: false
39093912
:path: "../../../packages/expo-battery/ios"
3913+
ExpoBlob:
3914+
inhibit_warnings: false
3915+
:path: "../../../packages/expo-blob/ios"
39103916
ExpoBlur:
39113917
inhibit_warnings: false
39123918
:path: "../../../packages/expo-blur/ios"
@@ -4274,6 +4280,7 @@ SPEC CHECKSUMS:
42744280
ExpoBackgroundFetch: 76c48b3cd9a4ee46e5267614a30fac804de6f33e
42754281
ExpoBackgroundTask: 9296d983f3d612359419e015ded65ebe9de30ba2
42764282
ExpoBattery: 6229d981d12dffb00c9e8e48181162729febb541
4283+
ExpoBlob: f28a229176d56d7f18a72f4c32218ec0302f68c4
42774284
ExpoBlur: 5d95f7ca771a0f3b9618466525dd68e46dc95f3a
42784285
ExpoBrightness: 05e750736f8886dcf235212b0caf85b0f605fc88
42794286
ExpoCalendar: 660542dc1c5ef98f46bedcc8745aa707df5d501a

apps/native-component-list/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"expo-background-fetch": "~13.1.5",
6565
"expo-background-task": "~0.2.7",
6666
"expo-battery": "~9.1.4",
67+
"expo-blob": "~0.1.0",
6768
"expo-blur": "~14.1.4",
6869
"expo-brightness": "~13.1.4",
6970
"expo-calendar": "~14.1.4",

apps/test-suite/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"expo-asset": "~11.1.5",
2020
"expo-av": "~15.1.4",
2121
"expo-background-fetch": "~13.1.5",
22+
"expo-blob": "~0.1.0",
2223
"expo-brightness": "~13.1.4",
2324
"expo-calendar": "~14.1.4",
2425
"expo-camera": "~16.1.6",

packages/expo-blob/.eslintrc.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// @generated by expo-module-scripts
2+
module.exports = require('expo-module-scripts/eslintrc.base.js');

packages/expo-blob/.npmignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# @generated by expo-module-scripts
2+
3+
# Exclude all top-level hidden directories by convention
4+
/.*/
5+
6+
# Exclude tarballs generated by `npm pack`
7+
/*.tgz
8+
9+
__mocks__
10+
__tests__
11+
__rsc_tests__
12+
13+
/babel.config.js
14+
/android/src/androidTest/
15+
/android/src/test/

packages/expo-blob/CHANGELOG.md

Whitespace-only changes.

packages/expo-blob/README.md

Whitespace-only changes.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
plugins {
2+
id 'com.android.library'
3+
id 'expo-module-gradle-plugin'
4+
}
5+
6+
group = 'host.exp.exponent'
7+
version = '0.1.0'
8+
9+
android {
10+
namespace "expo.modules.blob"
11+
defaultConfig {
12+
versionCode 1
13+
versionName '0.1.0'
14+
}
15+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<manifest>
2+
</manifest>
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
package expo.modules.blob
2+
3+
import android.util.Log
4+
import expo.modules.kotlin.records.Field
5+
import expo.modules.kotlin.records.Record
6+
import expo.modules.kotlin.sharedobjects.SharedObject
7+
import expo.modules.kotlin.typedarray.TypedArray
8+
import expo.modules.kotlin.types.EitherOfThree
9+
import expo.modules.kotlin.types.Enumerable
10+
11+
class Blob() : SharedObject() {
12+
var blobParts: List<InternalBlobPart> = listOf()
13+
var type: String = ""
14+
val size: Int by lazy {
15+
var size = 0
16+
for (bp in blobParts) {
17+
size += bp.size()
18+
}
19+
return@lazy size
20+
}
21+
22+
constructor(blobParts: List<InternalBlobPart>, type: String) : this() {
23+
this.blobParts = blobParts
24+
this.type = if(validType(type)) type.lowercase() else ""
25+
}
26+
27+
fun text(): String {
28+
var str = ""
29+
for (bp in blobParts) {
30+
str += bp.text()
31+
}
32+
return str
33+
}
34+
35+
private fun InternalBlobPart.offsetSlice(start: Int, end: Int, offset: Int): InternalBlobPart {
36+
var s: Int = start - offset
37+
var e: Int = end - offset
38+
if (s < 0) {
39+
s = 0
40+
}
41+
if (e > this.size()) {
42+
e = this.size()
43+
}
44+
return when (this) {
45+
is InternalBlobPart.StringPart -> InternalBlobPart.StringPart(string.substring(s, e))
46+
is InternalBlobPart.BlobPart -> InternalBlobPart.BlobPart(blob.slice(s, e, ""))
47+
is InternalBlobPart.BufferPart -> InternalBlobPart.BufferPart(
48+
buffer.slice(s..<e).toByteArray()
49+
)
50+
}
51+
}
52+
53+
fun slice(start: Int, end: Int, contentType: String): Blob {
54+
var i: Int = 0
55+
val bps: MutableList<InternalBlobPart> = mutableListOf()
56+
57+
for (bp in blobParts) {
58+
if (i + bp.size() <= start) {
59+
i += bp.size()
60+
continue
61+
}
62+
if (i >= end) {
63+
break
64+
}
65+
bps.add(bp.offsetSlice(start, end, i))
66+
i += bp.size()
67+
}
68+
69+
return Blob(bps, contentType)
70+
}
71+
}
72+
73+
private fun validType(type : String): Boolean {
74+
Log.d("UT", "type: " + type + ", type length: " + type.length.toString())
75+
for (c in type) {
76+
if (c.code < 0x20 || c.code > 0x7E) {
77+
return false;
78+
}
79+
}
80+
return true;
81+
}
82+
83+
typealias BlobPart = EitherOfThree<String, Blob, TypedArray>
84+
85+
private fun TypedArray.bytes(): ByteArray {
86+
var ba = ByteArray(this.byteLength)
87+
88+
for (i in 0..<this.byteLength) {
89+
ba[i] = this.readByte(i + this.byteOffset)
90+
}
91+
92+
return ba
93+
}
94+
95+
const val CR = '\r'
96+
const val LF = '\n'
97+
private fun String.toNativeNewlines(): String {
98+
var i = 0
99+
var str = ""
100+
101+
while (i < this.length) {
102+
if (this[i] == CR) {
103+
str += LF
104+
i += 1
105+
if (i < this.length && this[i] == LF) {
106+
i += 1
107+
}
108+
continue
109+
}
110+
str += this[i]
111+
i += 1
112+
}
113+
return str
114+
}
115+
116+
internal fun List<BlobPart>.internal(nativeNewlines: Boolean): List<InternalBlobPart> {
117+
return this.map() { bp: BlobPart ->
118+
if (bp.`is`(String::class)) {
119+
bp.get(String::class).let {
120+
val str = if (nativeNewlines) {
121+
it.toNativeNewlines()
122+
} else {
123+
it
124+
}
125+
InternalBlobPart.StringPart(str)
126+
}
127+
} else if (bp.`is`(Blob::class)) {
128+
bp.get(Blob::class).let {
129+
InternalBlobPart.BlobPart(it)
130+
}
131+
} else {
132+
bp.get(TypedArray::class).let {
133+
InternalBlobPart.BufferPart(it.bytes())
134+
}
135+
}
136+
}
137+
}
138+
139+
sealed class InternalBlobPart() {
140+
data class StringPart(val string: String) : InternalBlobPart()
141+
data class BlobPart(val blob: Blob) : InternalBlobPart()
142+
data class BufferPart(val buffer: ByteArray) : InternalBlobPart()
143+
144+
fun size(): Int {
145+
return when (this) {
146+
is StringPart -> string.length
147+
is BlobPart -> blob.size
148+
is BufferPart -> buffer.size
149+
}
150+
}
151+
152+
fun text(): String {
153+
return when (this) {
154+
is StringPart -> string
155+
is BlobPart -> blob.text()
156+
is BufferPart -> buffer.decodeToString()
157+
}
158+
}
159+
}
160+
161+
enum class EndingType(val str: String = "transparent") : Enumerable {
162+
TRANSPARENT("transparent"), NATIVE("native"),
163+
}
164+
165+
internal const val DEFAULT_TYPE = ""
166+
167+
class BlobOptionsBag : Record {
168+
@Field
169+
val type: String = ""
170+
171+
@Field
172+
val endings: EndingType = EndingType.TRANSPARENT
173+
}

0 commit comments

Comments
 (0)