/**
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import buffer from '@ohos.buffer';
import { ContactInfo } from '../data/ContactInfo';
import LogUtils from './LogUtils';
import DatabaseUtils from './DatabaseUtils';
const SHORT_UNIQUE_KEY_LENGTH = 8;
const SHORT_UUID_LENGTH = 13;
const LONG_UUID_LENGTH = 20;
const spaceRex = new RegExp('\\s+', 'g');
const dashReg = new RegExp('[\-\]', 'g');
/**
* Handle string util
*/
export class StringUtil {
static paddingLeft(str: string, padCh: string, len: number): string {
while (str.length < len) {
str = padCh + str;
}
return str;
}
/**
* If string is empty
*
* @param str which to handle
* @returns if string is empty
*/
static isEmpty(str: string | undefined | null): boolean {
return str === undefined || str === null || str.length === 0;
}
/**
* If string is equals ignore case
*
* @param str which to handle
* @returns string removed space
*/
static equalsIgnoreCase(str: string, str1: string): boolean {
if (StringUtil.isEmpty(str) && StringUtil.isEmpty(str1)) {
return true;
}
if (StringUtil.isEmpty(str) || StringUtil.isEmpty(str1)) {
return false;
}
return str1.toUpperCase() === str.toUpperCase();
}
/**
* Get data type from mime type
*
* @param str which to handle
* @returns removed space str
*/
static getType(mimeType: string | undefined): string {
if (mimeType === undefined || StringUtil.isEmpty(mimeType)) {
return '';
}
if (mimeType.indexOf('/') === -1) {
return '';
}
let type = mimeType.split('/')[1];
if (StringUtil.isEmpty(type)) {
return '';
}
if (type.indexOf('_') === -1) {
return type;
}
return type.split('_')[0];
}
/**
* Remove str space
*
* @param str which to handle
* @returns string removed space
*/
static removeSpace(str: string): string {
if (StringUtil.isEmpty(str)) {
return '';
}
str = str.trim();
while (str.indexOf(' ') != -1) {
str = str.replace(' ', '');
}
return str;
}
static removeSpaceNew(str: string): string {
if (StringUtil.isEmpty(str)) {
return '';
}
return str.replace(spaceRex, '').replace(dashReg, '');
}
static maskSensitiveInfo(str: string | undefined | null): string {
try {
if (str === undefined || str === null || str.length === 0) {
return '';
}
// 只有一个字符,大概率是姓名只有一个字,此时不打印
if (str.length <= 1) {
return `*:${str.length}`;
}
// 只有2个字符时,打印首字母跟长度2,与下面统一
if (str.length <= 2) {
return `${str.substring(0, 1)}:${str.length}`;
}
// 大概率是姓名、公司,打印首尾字符
if (str.length <= 7) {
return `${str.substring(0, 1)}:${str.substring(str.length - 1, str.length)}:${str.length}`;
}
// 号码或者座机,打印前三位,后四位
if (str.length <= 11) {
return `${str.substring(0, 3)}:${str.substring(str.length - 4, str.length)}:${str.length}`;
}
// 对于带有+86这样的手机,打印前六位
if (str.length <= 14) {
return `${str.substring(0, 6)}:${str.substring(str.length - 4, str.length)}:${str.length}`;
}
return `${str.substring(0, 3)}:${str.substring(str.length - 4, str.length)}:${str.length}`;
} catch (e) {
LogUtils.e('StringUtil', 'maskSensitiveInfo error:' + e.message);
return `***`;
}
}
static fromBase64(str: string): string {
try {
if (StringUtil.isEmpty(str)) {
return '';
}
return buffer.from(str, 'base64').toString('utf8');
} catch (e) {
LogUtils.e('StringUtil', 'fromBase64 error:' + e.message);
return str;
}
}
static getVcardLogStr(vcard: string): string {
if (!vcard) {
return '';
}
const arr = vcard.split(/[\r?\n]/);
const resultArr = arr.filter((line: string) => {
if (!line?.trim()) {
return false;
}
if (line.startsWith('PHOTO;ENCODING=BASE64')) {
return false;
}
return true;
});
return StringUtil.maskSensitiveInfo(resultArr.join('\r\n'));
}
static getContactInfoLogStr(contactInfo: ContactInfo): string {
try {
const str = JSON.stringify(contactInfo, (key: string, value: Object) => {
// 如果属性名是"photo",则过滤掉该属性
if (key === 'photo') {
return undefined; // 从序列化结果中排除这个属性
}
return value; // 保留这个属性
});
return StringUtil.maskSensitiveInfo(str);
} catch (e) {
LogUtils.e('StringUtil', 'getContactInfoLogStr error:' + e.message);
return '';
}
}
static async printLogStr(tag: string, str: string) {
// 实测2400多长度日志可能就被截断了,打印重复联系人列表,删除列表等场景都需要保证完整,不被截断丢弃
let limit = 2200;
let start = 0;
let end = 2200;
if (str.length <= limit) {
LogUtils.w(tag, str);
return;
}
while (start < str.length) {
LogUtils.w(tag, str.slice(start, end));
start += limit;
end += limit;
await DatabaseUtils.delay(120);
}
}
static getShortUniqueKey(uniqueKey: string): string {
if (!uniqueKey || !uniqueKey.length) {
return '';
}
return uniqueKey.slice(0, SHORT_UNIQUE_KEY_LENGTH);
}
static getShortUuid(uuid: string | null, long = false): string {
if (!uuid || !uuid.length) {
return '';
}
// 双的 uuid 前面都一样,所以打印后面子串
return uuid.slice(long ? -LONG_UUID_LENGTH : -SHORT_UUID_LENGTH);
}
}