am 455d4100: Merge "Initial checkin of "foundation" library for future stagefright development." into kraken
This commit is contained in:
51
include/media/stagefright/foundation/AAtomizer.h
Normal file
51
include/media/stagefright/foundation/AAtomizer.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef A_ATOMIZER_H_
|
||||
|
||||
#define A_ATOMIZER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <media/stagefright/foundation/ABase.h>
|
||||
#include <media/stagefright/foundation/AString.h>
|
||||
#include <utils/List.h>
|
||||
#include <utils/Vector.h>
|
||||
#include <utils/threads.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
struct AAtomizer {
|
||||
static const char *Atomize(const char *name);
|
||||
|
||||
private:
|
||||
static AAtomizer gAtomizer;
|
||||
|
||||
Mutex mLock;
|
||||
Vector<List<AString> > mAtoms;
|
||||
|
||||
AAtomizer();
|
||||
|
||||
const char *atomize(const char *name);
|
||||
|
||||
static uint32_t Hash(const char *s);
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(AAtomizer);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // A_ATOMIZER_H_
|
||||
25
include/media/stagefright/foundation/ABase.h
Normal file
25
include/media/stagefright/foundation/ABase.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef A_BASE_H_
|
||||
|
||||
#define A_BASE_H_
|
||||
|
||||
#define DISALLOW_EVIL_CONSTRUCTORS(name) \
|
||||
name(const name &); \
|
||||
name &operator=(const name &)
|
||||
|
||||
#endif // A_BASE_H_
|
||||
71
include/media/stagefright/foundation/ABuffer.h
Normal file
71
include/media/stagefright/foundation/ABuffer.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef A_BUFFER_H_
|
||||
|
||||
#define A_BUFFER_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <media/stagefright/foundation/ABase.h>
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
struct AMessage;
|
||||
|
||||
struct ABuffer : public RefBase {
|
||||
ABuffer(size_t capacity);
|
||||
ABuffer(void *data, size_t capacity);
|
||||
|
||||
void setFarewellMessage(const sp<AMessage> msg);
|
||||
|
||||
uint8_t *base() { return (uint8_t *)mData; }
|
||||
uint8_t *data() { return (uint8_t *)mData + mRangeOffset; }
|
||||
size_t capacity() const { return mCapacity; }
|
||||
size_t size() const { return mRangeLength; }
|
||||
size_t offset() const { return mRangeOffset; }
|
||||
|
||||
void setRange(size_t offset, size_t size);
|
||||
|
||||
void setInt32Data(int32_t data) { mInt32Data = data; }
|
||||
int32_t int32Data() const { return mInt32Data; }
|
||||
|
||||
sp<AMessage> meta();
|
||||
|
||||
protected:
|
||||
virtual ~ABuffer();
|
||||
|
||||
private:
|
||||
sp<AMessage> mFarewell;
|
||||
sp<AMessage> mMeta;
|
||||
|
||||
void *mData;
|
||||
size_t mCapacity;
|
||||
size_t mRangeOffset;
|
||||
size_t mRangeLength;
|
||||
|
||||
int32_t mInt32Data;
|
||||
|
||||
bool mOwnsData;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ABuffer);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // A_BUFFER_H_
|
||||
105
include/media/stagefright/foundation/ADebug.h
Normal file
105
include/media/stagefright/foundation/ADebug.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef A_DEBUG_H_
|
||||
|
||||
#define A_DEBUG_H_
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <media/stagefright/foundation/ABase.h>
|
||||
#include <media/stagefright/foundation/AString.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
enum LogType {
|
||||
VERBOSE,
|
||||
INFO,
|
||||
WARNING,
|
||||
ERROR,
|
||||
FATAL,
|
||||
};
|
||||
|
||||
struct Logger {
|
||||
Logger(LogType type);
|
||||
virtual ~Logger();
|
||||
|
||||
template<class T> Logger &operator<<(const T &x) {
|
||||
mMessage.append(x);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
android::AString mMessage;
|
||||
LogType mLogType;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(Logger);
|
||||
};
|
||||
|
||||
const char *LeafName(const char *s);
|
||||
|
||||
#undef LOG
|
||||
#define LOG(type) Logger(type) << LeafName(__FILE__) << ":" << __LINE__ << " "
|
||||
|
||||
#define CHECK(condition) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
LOG(FATAL) << "CHECK(" #condition ") failed."; \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define MAKE_COMPARATOR(suffix,op) \
|
||||
template<class A, class B> \
|
||||
AString Compare_##suffix(const A &a, const B &b) { \
|
||||
AString res; \
|
||||
if (!(a op b)) { \
|
||||
res.append(a); \
|
||||
res.append(" vs. "); \
|
||||
res.append(b); \
|
||||
} \
|
||||
return res; \
|
||||
}
|
||||
|
||||
MAKE_COMPARATOR(EQ,==)
|
||||
MAKE_COMPARATOR(NE,!=)
|
||||
MAKE_COMPARATOR(LE,<=)
|
||||
MAKE_COMPARATOR(GE,>=)
|
||||
MAKE_COMPARATOR(LT,<)
|
||||
MAKE_COMPARATOR(GT,>)
|
||||
|
||||
#define CHECK_OP(x,y,suffix,op) \
|
||||
do { \
|
||||
AString ___res = Compare_##suffix(x, y); \
|
||||
if (!___res.empty()) { \
|
||||
LOG(FATAL) << "CHECK_" #suffix "(" #x "," #y ") failed: " \
|
||||
<< ___res; \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define CHECK_EQ(x,y) CHECK_OP(x,y,EQ,==)
|
||||
#define CHECK_NE(x,y) CHECK_OP(x,y,NE,!=)
|
||||
#define CHECK_LE(x,y) CHECK_OP(x,y,LE,<=)
|
||||
#define CHECK_LT(x,y) CHECK_OP(x,y,LT,<)
|
||||
#define CHECK_GE(x,y) CHECK_OP(x,y,GE,>=)
|
||||
#define CHECK_GT(x,y) CHECK_OP(x,y,GT,>)
|
||||
|
||||
#define TRESPASS() LOG(FATAL) << "Should not be here."
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // A_DEBUG_H_
|
||||
|
||||
54
include/media/stagefright/foundation/AHandler.h
Normal file
54
include/media/stagefright/foundation/AHandler.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef A_HANDLER_H_
|
||||
|
||||
#define A_HANDLER_H_
|
||||
|
||||
#include <media/stagefright/foundation/ALooper.h>
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
struct AMessage;
|
||||
|
||||
struct AHandler : public RefBase {
|
||||
AHandler()
|
||||
: mID(0) {
|
||||
}
|
||||
|
||||
ALooper::handler_id id() const {
|
||||
return mID;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void onMessageReceived(const sp<AMessage> &msg) = 0;
|
||||
|
||||
private:
|
||||
friend struct ALooperRoster;
|
||||
|
||||
ALooper::handler_id mID;
|
||||
|
||||
void setID(ALooper::handler_id id) {
|
||||
mID = id;
|
||||
}
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(AHandler);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // A_HANDLER_H_
|
||||
75
include/media/stagefright/foundation/ALooper.h
Normal file
75
include/media/stagefright/foundation/ALooper.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef A_LOOPER_H_
|
||||
|
||||
#define A_LOOPER_H_
|
||||
|
||||
#include <media/stagefright/foundation/ABase.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/List.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/threads.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
struct AHandler;
|
||||
struct AMessage;
|
||||
|
||||
struct ALooper : public RefBase {
|
||||
typedef int32_t event_id;
|
||||
typedef int32_t handler_id;
|
||||
|
||||
ALooper();
|
||||
|
||||
handler_id registerHandler(const sp<AHandler> &handler);
|
||||
void unregisterHandler(handler_id handlerID);
|
||||
|
||||
status_t start(bool runOnCallingThread = false);
|
||||
status_t stop();
|
||||
|
||||
static int64_t GetNowUs();
|
||||
|
||||
protected:
|
||||
virtual ~ALooper();
|
||||
|
||||
private:
|
||||
friend struct ALooperRoster;
|
||||
|
||||
struct Event {
|
||||
int64_t mWhenUs;
|
||||
sp<AMessage> mMessage;
|
||||
};
|
||||
|
||||
Mutex mLock;
|
||||
Condition mQueueChangedCondition;
|
||||
|
||||
List<Event> mEventQueue;
|
||||
|
||||
struct LooperThread;
|
||||
sp<LooperThread> mThread;
|
||||
bool mRunningLocally;
|
||||
|
||||
void post(const sp<AMessage> &msg, int64_t delayUs);
|
||||
bool loop();
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ALooper);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // A_LOOPER_H_
|
||||
52
include/media/stagefright/foundation/ALooperRoster.h
Normal file
52
include/media/stagefright/foundation/ALooperRoster.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef A_LOOPER_ROSTER_H_
|
||||
|
||||
#define A_LOOPER_ROSTER_H_
|
||||
|
||||
#include <media/stagefright/foundation/ALooper.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
struct ALooperRoster {
|
||||
ALooperRoster();
|
||||
|
||||
ALooper::handler_id registerHandler(
|
||||
const sp<ALooper> looper, const sp<AHandler> &handler);
|
||||
|
||||
void unregisterHandler(ALooper::handler_id handlerID);
|
||||
|
||||
void postMessage(const sp<AMessage> &msg, int64_t delayUs = 0);
|
||||
void deliverMessage(const sp<AMessage> &msg);
|
||||
|
||||
private:
|
||||
struct HandlerInfo {
|
||||
sp<ALooper> mLooper;
|
||||
sp<AHandler> mHandler;
|
||||
};
|
||||
|
||||
Mutex mLock;
|
||||
KeyedVector<ALooper::handler_id, HandlerInfo> mHandlers;
|
||||
ALooper::handler_id mNextHandlerID;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ALooperRoster);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // A_LOOPER_ROSTER_H_
|
||||
113
include/media/stagefright/foundation/AMessage.h
Normal file
113
include/media/stagefright/foundation/AMessage.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef A_MESSAGE_H_
|
||||
|
||||
#define A_MESSAGE_H_
|
||||
|
||||
#include <media/stagefright/foundation/ABase.h>
|
||||
#include <media/stagefright/foundation/ALooper.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
struct AString;
|
||||
|
||||
struct AMessage : public RefBase {
|
||||
AMessage(uint32_t what = 0, ALooper::handler_id target = 0);
|
||||
|
||||
void setWhat(uint32_t what);
|
||||
uint32_t what() const;
|
||||
|
||||
void setTarget(ALooper::handler_id target);
|
||||
ALooper::handler_id target() const;
|
||||
|
||||
void setInt32(const char *name, int32_t value);
|
||||
void setInt64(const char *name, int64_t value);
|
||||
void setSize(const char *name, size_t value);
|
||||
void setFloat(const char *name, float value);
|
||||
void setDouble(const char *name, double value);
|
||||
void setPointer(const char *name, void *value);
|
||||
void setString(const char *name, const char *s, ssize_t len = -1);
|
||||
void setObject(const char *name, const sp<RefBase> &obj);
|
||||
void setMessage(const char *name, const sp<AMessage> &obj);
|
||||
|
||||
bool findInt32(const char *name, int32_t *value) const;
|
||||
bool findInt64(const char *name, int64_t *value) const;
|
||||
bool findSize(const char *name, size_t *value) const;
|
||||
bool findFloat(const char *name, float *value) const;
|
||||
bool findDouble(const char *name, double *value) const;
|
||||
bool findPointer(const char *name, void **value) const;
|
||||
bool findString(const char *name, AString *value) const;
|
||||
bool findObject(const char *name, sp<RefBase> *obj) const;
|
||||
bool findMessage(const char *name, sp<AMessage> *obj) const;
|
||||
|
||||
void post(int64_t delayUs = 0);
|
||||
|
||||
sp<AMessage> dup() const;
|
||||
|
||||
protected:
|
||||
virtual ~AMessage();
|
||||
|
||||
private:
|
||||
enum Type {
|
||||
kTypeInt32,
|
||||
kTypeInt64,
|
||||
kTypeSize,
|
||||
kTypeFloat,
|
||||
kTypeDouble,
|
||||
kTypePointer,
|
||||
kTypeString,
|
||||
kTypeObject,
|
||||
kTypeMessage,
|
||||
};
|
||||
|
||||
uint32_t mWhat;
|
||||
ALooper::handler_id mTarget;
|
||||
|
||||
struct Item {
|
||||
union {
|
||||
int32_t int32Value;
|
||||
int64_t int64Value;
|
||||
size_t sizeValue;
|
||||
float floatValue;
|
||||
double doubleValue;
|
||||
void *ptrValue;
|
||||
RefBase *refValue;
|
||||
AString *stringValue;
|
||||
} u;
|
||||
const char *mName;
|
||||
Type mType;
|
||||
};
|
||||
|
||||
enum {
|
||||
kMaxNumItems = 16
|
||||
};
|
||||
Item mItems[kMaxNumItems];
|
||||
size_t mNumItems;
|
||||
|
||||
void clear();
|
||||
Item *allocateItem(const char *name);
|
||||
void freeItem(Item *item);
|
||||
const Item *findItem(const char *name, Type type) const;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(AMessage);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // A_MESSAGE_H_
|
||||
94
include/media/stagefright/foundation/AString.h
Normal file
94
include/media/stagefright/foundation/AString.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef A_STRING_H_
|
||||
|
||||
#define A_STRING_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
struct AString {
|
||||
AString();
|
||||
AString(const char *s);
|
||||
AString(const char *s, size_t size);
|
||||
AString(const AString &from);
|
||||
AString(const AString &from, size_t offset, size_t n);
|
||||
~AString();
|
||||
|
||||
AString &operator=(const AString &from);
|
||||
void setTo(const char *s);
|
||||
void setTo(const char *s, size_t size);
|
||||
void setTo(const AString &from, size_t offset, size_t n);
|
||||
|
||||
size_t size() const;
|
||||
const char *c_str() const;
|
||||
|
||||
bool empty() const;
|
||||
|
||||
void clear();
|
||||
void trim();
|
||||
void erase(size_t start, size_t n);
|
||||
|
||||
void append(char c) { append(&c, 1); }
|
||||
void append(const char *s);
|
||||
void append(const char *s, size_t size);
|
||||
void append(const AString &from);
|
||||
void append(const AString &from, size_t offset, size_t n);
|
||||
void append(int x);
|
||||
void append(unsigned x);
|
||||
void append(long x);
|
||||
void append(unsigned long x);
|
||||
void append(long long x);
|
||||
void append(unsigned long long x);
|
||||
void append(float x);
|
||||
void append(double x);
|
||||
void append(void *x);
|
||||
|
||||
void insert(const AString &from, size_t insertionPos);
|
||||
void insert(const char *from, size_t size, size_t insertionPos);
|
||||
|
||||
ssize_t find(const char *substring, size_t start = 0) const;
|
||||
|
||||
size_t hash() const;
|
||||
|
||||
bool operator==(const AString &other) const;
|
||||
bool operator<(const AString &other) const;
|
||||
bool operator>(const AString &other) const;
|
||||
|
||||
int compare(const AString &other) const;
|
||||
|
||||
bool startsWith(const char *prefix) const;
|
||||
|
||||
void tolower();
|
||||
|
||||
private:
|
||||
static const char *kEmptyString;
|
||||
|
||||
char *mData;
|
||||
size_t mSize;
|
||||
size_t mAllocSize;
|
||||
|
||||
void makeMutable();
|
||||
};
|
||||
|
||||
AString StringPrintf(const char *format, ...);
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // A_STRING_H_
|
||||
|
||||
33
include/media/stagefright/foundation/base64.h
Normal file
33
include/media/stagefright/foundation/base64.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef BASE_64_H_
|
||||
|
||||
#define BASE_64_H_
|
||||
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
struct ABuffer;
|
||||
struct AString;
|
||||
|
||||
sp<ABuffer> decodeBase64(const AString &s);
|
||||
void encodeBase64(const void *data, size_t size, AString *out);
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // BASE_64_H_
|
||||
29
include/media/stagefright/foundation/hexdump.h
Normal file
29
include/media/stagefright/foundation/hexdump.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef HEXDUMP_H_
|
||||
|
||||
#define HEXDUMP_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
void hexdump(const void *_data, size_t size);
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // HEXDUMP_H_
|
||||
67
media/libstagefright/foundation/AAtomizer.cpp
Normal file
67
media/libstagefright/foundation/AAtomizer.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "AAtomizer.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
// static
|
||||
AAtomizer AAtomizer::gAtomizer;
|
||||
|
||||
// static
|
||||
const char *AAtomizer::Atomize(const char *name) {
|
||||
return gAtomizer.atomize(name);
|
||||
}
|
||||
|
||||
AAtomizer::AAtomizer() {
|
||||
for (size_t i = 0; i < 128; ++i) {
|
||||
mAtoms.push(List<AString>());
|
||||
}
|
||||
}
|
||||
|
||||
const char *AAtomizer::atomize(const char *name) {
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
|
||||
const size_t n = mAtoms.size();
|
||||
size_t index = AAtomizer::Hash(name) % n;
|
||||
List<AString> &entry = mAtoms.editItemAt(index);
|
||||
List<AString>::iterator it = entry.begin();
|
||||
while (it != entry.end()) {
|
||||
if ((*it) == name) {
|
||||
return (*it).c_str();
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
entry.push_back(AString(name));
|
||||
|
||||
return (*--entry.end()).c_str();
|
||||
}
|
||||
|
||||
// static
|
||||
uint32_t AAtomizer::Hash(const char *s) {
|
||||
uint32_t sum = 0;
|
||||
while (*s != '\0') {
|
||||
sum = (sum * 31) + *s;
|
||||
++s;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
76
media/libstagefright/foundation/ABuffer.cpp
Normal file
76
media/libstagefright/foundation/ABuffer.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ABuffer.h"
|
||||
|
||||
#include "ADebug.h"
|
||||
#include "ALooper.h"
|
||||
#include "AMessage.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
ABuffer::ABuffer(size_t capacity)
|
||||
: mData(malloc(capacity)),
|
||||
mCapacity(capacity),
|
||||
mRangeOffset(0),
|
||||
mRangeLength(capacity),
|
||||
mInt32Data(0),
|
||||
mOwnsData(true) {
|
||||
}
|
||||
|
||||
ABuffer::ABuffer(void *data, size_t capacity)
|
||||
: mData(data),
|
||||
mCapacity(capacity),
|
||||
mRangeOffset(0),
|
||||
mRangeLength(capacity),
|
||||
mInt32Data(0),
|
||||
mOwnsData(false) {
|
||||
}
|
||||
|
||||
ABuffer::~ABuffer() {
|
||||
if (mOwnsData) {
|
||||
if (mData != NULL) {
|
||||
free(mData);
|
||||
mData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (mFarewell != NULL) {
|
||||
mFarewell->post();
|
||||
}
|
||||
}
|
||||
|
||||
void ABuffer::setRange(size_t offset, size_t size) {
|
||||
CHECK_LE(offset, mCapacity);
|
||||
CHECK_LE(offset + size, mCapacity);
|
||||
|
||||
mRangeOffset = offset;
|
||||
mRangeLength = size;
|
||||
}
|
||||
|
||||
void ABuffer::setFarewellMessage(const sp<AMessage> msg) {
|
||||
mFarewell = msg;
|
||||
}
|
||||
|
||||
sp<AMessage> ABuffer::meta() {
|
||||
if (mMeta == NULL) {
|
||||
mMeta = new AMessage;
|
||||
}
|
||||
return mMeta;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
76
media/libstagefright/foundation/ADebug.cpp
Normal file
76
media/libstagefright/foundation/ADebug.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ADebug.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <cutils/log.h>
|
||||
#endif
|
||||
|
||||
namespace android {
|
||||
|
||||
Logger::Logger(LogType type)
|
||||
: mLogType(type) {
|
||||
switch (mLogType) {
|
||||
case VERBOSE:
|
||||
mMessage = "V ";
|
||||
break;
|
||||
case INFO:
|
||||
mMessage = "I ";
|
||||
break;
|
||||
case WARNING:
|
||||
mMessage = "W ";
|
||||
break;
|
||||
case ERROR:
|
||||
mMessage = "E ";
|
||||
break;
|
||||
case FATAL:
|
||||
mMessage = "F ";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Logger::~Logger() {
|
||||
if (mLogType == VERBOSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
mMessage.append("\n");
|
||||
|
||||
#if defined(ANDROID) && 1
|
||||
LOG_PRI(ANDROID_LOG_INFO, "ADebug", "%s", mMessage.c_str());
|
||||
#else
|
||||
fprintf(stderr, mMessage.c_str());
|
||||
fflush(stderr);
|
||||
#endif
|
||||
|
||||
if (mLogType == FATAL) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
const char *LeafName(const char *s) {
|
||||
const char *lastSlash = strrchr(s, '/');
|
||||
return lastSlash != NULL ? lastSlash + 1 : s;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
196
media/libstagefright/foundation/ALooper.cpp
Normal file
196
media/libstagefright/foundation/ALooper.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
#define LOG_TAG "ALooper"
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "ALooper.h"
|
||||
|
||||
#include "AHandler.h"
|
||||
#include "ALooperRoster.h"
|
||||
#include "AMessage.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
ALooperRoster gLooperRoster;
|
||||
|
||||
struct ALooper::LooperThread : public Thread {
|
||||
LooperThread(ALooper *looper)
|
||||
: mLooper(looper) {
|
||||
}
|
||||
|
||||
virtual bool threadLoop() {
|
||||
return mLooper->loop();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~LooperThread() {}
|
||||
|
||||
private:
|
||||
ALooper *mLooper;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(LooperThread);
|
||||
};
|
||||
|
||||
// static
|
||||
int64_t ALooper::GetNowUs() {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
return (int64_t)tv.tv_sec * 1000000ll + tv.tv_usec;
|
||||
}
|
||||
|
||||
ALooper::ALooper()
|
||||
: mRunningLocally(false) {
|
||||
}
|
||||
|
||||
ALooper::~ALooper() {
|
||||
stop();
|
||||
}
|
||||
|
||||
ALooper::handler_id ALooper::registerHandler(const sp<AHandler> &handler) {
|
||||
return gLooperRoster.registerHandler(this, handler);
|
||||
}
|
||||
|
||||
void ALooper::unregisterHandler(handler_id handlerID) {
|
||||
gLooperRoster.unregisterHandler(handlerID);
|
||||
}
|
||||
|
||||
status_t ALooper::start(bool runOnCallingThread) {
|
||||
if (runOnCallingThread) {
|
||||
{
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
|
||||
if (mThread != NULL || mRunningLocally) {
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
|
||||
mRunningLocally = true;
|
||||
}
|
||||
|
||||
do {
|
||||
} while (loop());
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
|
||||
if (mThread != NULL || mRunningLocally) {
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
|
||||
mThread = new LooperThread(this);
|
||||
|
||||
status_t err = mThread->run("ALooper");
|
||||
if (err != OK) {
|
||||
mThread.clear();
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
status_t ALooper::stop() {
|
||||
sp<LooperThread> thread;
|
||||
bool runningLocally;
|
||||
|
||||
{
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
|
||||
thread = mThread;
|
||||
runningLocally = mRunningLocally;
|
||||
mThread.clear();
|
||||
mRunningLocally = false;
|
||||
}
|
||||
|
||||
if (thread == NULL && !runningLocally) {
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
|
||||
if (thread != NULL) {
|
||||
thread->requestExit();
|
||||
}
|
||||
|
||||
mQueueChangedCondition.signal();
|
||||
|
||||
if (!runningLocally) {
|
||||
thread->requestExitAndWait();
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void ALooper::post(const sp<AMessage> &msg, int64_t delayUs) {
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
|
||||
int64_t whenUs;
|
||||
if (delayUs > 0) {
|
||||
whenUs = GetNowUs() + delayUs;
|
||||
} else {
|
||||
whenUs = GetNowUs();
|
||||
}
|
||||
|
||||
List<Event>::iterator it = mEventQueue.begin();
|
||||
while (it != mEventQueue.end() && (*it).mWhenUs <= whenUs) {
|
||||
++it;
|
||||
}
|
||||
|
||||
Event event;
|
||||
event.mWhenUs = whenUs;
|
||||
event.mMessage = msg;
|
||||
|
||||
if (it == mEventQueue.begin()) {
|
||||
mQueueChangedCondition.signal();
|
||||
}
|
||||
|
||||
mEventQueue.insert(it, event);
|
||||
}
|
||||
|
||||
bool ALooper::loop() {
|
||||
Event event;
|
||||
|
||||
{
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
if (mThread == NULL && !mRunningLocally) {
|
||||
return false;
|
||||
}
|
||||
if (mEventQueue.empty()) {
|
||||
mQueueChangedCondition.wait(mLock);
|
||||
return true;
|
||||
}
|
||||
int64_t whenUs = (*mEventQueue.begin()).mWhenUs;
|
||||
int64_t nowUs = GetNowUs();
|
||||
|
||||
if (whenUs > nowUs) {
|
||||
int64_t delayUs = whenUs - nowUs;
|
||||
mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
event = *mEventQueue.begin();
|
||||
mEventQueue.erase(mEventQueue.begin());
|
||||
}
|
||||
|
||||
gLooperRoster.deliverMessage(event.mMessage);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
100
media/libstagefright/foundation/ALooperRoster.cpp
Normal file
100
media/libstagefright/foundation/ALooperRoster.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
#define LOG_TAG "ALooperRoster"
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include "ALooperRoster.h"
|
||||
|
||||
#include "ADebug.h"
|
||||
#include "AHandler.h"
|
||||
#include "AMessage.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
ALooperRoster::ALooperRoster()
|
||||
: mNextHandlerID(1) {
|
||||
}
|
||||
|
||||
ALooper::handler_id ALooperRoster::registerHandler(
|
||||
const sp<ALooper> looper, const sp<AHandler> &handler) {
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
|
||||
if (handler->id() != 0) {
|
||||
CHECK(!"A handler must only be registered once.");
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
|
||||
HandlerInfo info;
|
||||
info.mLooper = looper;
|
||||
info.mHandler = handler;
|
||||
ALooper::handler_id handlerID = mNextHandlerID++;
|
||||
mHandlers.add(handlerID, info);
|
||||
|
||||
handler->setID(handlerID);
|
||||
|
||||
return handlerID;
|
||||
}
|
||||
|
||||
void ALooperRoster::unregisterHandler(ALooper::handler_id handlerID) {
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
|
||||
ssize_t index = mHandlers.indexOfKey(handlerID);
|
||||
CHECK(index >= 0);
|
||||
|
||||
const HandlerInfo &info = mHandlers.valueAt(index);
|
||||
info.mHandler->setID(0);
|
||||
|
||||
mHandlers.removeItemsAt(index);
|
||||
}
|
||||
|
||||
void ALooperRoster::postMessage(
|
||||
const sp<AMessage> &msg, int64_t delayUs) {
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
|
||||
ssize_t index = mHandlers.indexOfKey(msg->target());
|
||||
|
||||
if (index < 0) {
|
||||
LOG(WARNING) << "failed to post message. Target handler not registered.";
|
||||
return;
|
||||
}
|
||||
|
||||
const HandlerInfo &info = mHandlers.valueAt(index);
|
||||
info.mLooper->post(msg, delayUs);
|
||||
}
|
||||
|
||||
void ALooperRoster::deliverMessage(const sp<AMessage> &msg) {
|
||||
sp<AHandler> handler;
|
||||
|
||||
{
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
|
||||
ssize_t index = mHandlers.indexOfKey(msg->target());
|
||||
|
||||
if (index < 0) {
|
||||
LOG(WARNING) << "failed to deliver message. Target handler not registered.";
|
||||
return;
|
||||
}
|
||||
|
||||
const HandlerInfo &info = mHandlers.valueAt(index);
|
||||
handler = info.mHandler;
|
||||
}
|
||||
|
||||
handler->onMessageReceived(msg);
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
241
media/libstagefright/foundation/AMessage.cpp
Normal file
241
media/libstagefright/foundation/AMessage.cpp
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "AMessage.h"
|
||||
|
||||
#include "AAtomizer.h"
|
||||
#include "ADebug.h"
|
||||
#include "ALooperRoster.h"
|
||||
#include "AString.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
AMessage::AMessage(uint32_t what, ALooper::handler_id target)
|
||||
: mWhat(what),
|
||||
mTarget(target),
|
||||
mNumItems(0) {
|
||||
}
|
||||
|
||||
AMessage::~AMessage() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void AMessage::setWhat(uint32_t what) {
|
||||
mWhat = what;
|
||||
}
|
||||
|
||||
uint32_t AMessage::what() const {
|
||||
return mWhat;
|
||||
}
|
||||
|
||||
void AMessage::setTarget(ALooper::handler_id handlerID) {
|
||||
mTarget = handlerID;
|
||||
}
|
||||
|
||||
ALooper::handler_id AMessage::target() const {
|
||||
return mTarget;
|
||||
}
|
||||
|
||||
void AMessage::clear() {
|
||||
for (size_t i = 0; i < mNumItems; ++i) {
|
||||
Item *item = &mItems[i];
|
||||
freeItem(item);
|
||||
}
|
||||
mNumItems = 0;
|
||||
}
|
||||
|
||||
void AMessage::freeItem(Item *item) {
|
||||
switch (item->mType) {
|
||||
case kTypeString:
|
||||
{
|
||||
delete item->u.stringValue;
|
||||
break;
|
||||
}
|
||||
|
||||
case kTypeObject:
|
||||
case kTypeMessage:
|
||||
{
|
||||
if (item->u.refValue != NULL) {
|
||||
item->u.refValue->decStrong(this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AMessage::Item *AMessage::allocateItem(const char *name) {
|
||||
name = AAtomizer::Atomize(name);
|
||||
|
||||
size_t i = 0;
|
||||
while (i < mNumItems && mItems[i].mName != name) {
|
||||
++i;
|
||||
}
|
||||
|
||||
Item *item;
|
||||
|
||||
if (i < mNumItems) {
|
||||
item = &mItems[i];
|
||||
freeItem(item);
|
||||
} else {
|
||||
CHECK(mNumItems < kMaxNumItems);
|
||||
i = mNumItems++;
|
||||
item = &mItems[i];
|
||||
|
||||
item->mName = name;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
const AMessage::Item *AMessage::findItem(
|
||||
const char *name, Type type) const {
|
||||
name = AAtomizer::Atomize(name);
|
||||
|
||||
for (size_t i = 0; i < mNumItems; ++i) {
|
||||
const Item *item = &mItems[i];
|
||||
|
||||
if (item->mName == name) {
|
||||
return item->mType == type ? item : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define BASIC_TYPE(NAME,FIELDNAME,TYPENAME) \
|
||||
void AMessage::set##NAME(const char *name, TYPENAME value) { \
|
||||
Item *item = allocateItem(name); \
|
||||
\
|
||||
item->mType = kType##NAME; \
|
||||
item->u.FIELDNAME = value; \
|
||||
} \
|
||||
\
|
||||
bool AMessage::find##NAME(const char *name, TYPENAME *value) const { \
|
||||
const Item *item = findItem(name, kType##NAME); \
|
||||
if (item) { \
|
||||
*value = item->u.FIELDNAME; \
|
||||
return true; \
|
||||
} \
|
||||
return false; \
|
||||
}
|
||||
|
||||
BASIC_TYPE(Int32,int32Value,int32_t)
|
||||
BASIC_TYPE(Int64,int64Value,int64_t)
|
||||
BASIC_TYPE(Size,sizeValue,size_t)
|
||||
BASIC_TYPE(Float,floatValue,float)
|
||||
BASIC_TYPE(Double,doubleValue,double)
|
||||
BASIC_TYPE(Pointer,ptrValue,void *)
|
||||
|
||||
#undef BASIC_TYPE
|
||||
|
||||
void AMessage::setString(
|
||||
const char *name, const char *s, ssize_t len) {
|
||||
Item *item = allocateItem(name);
|
||||
item->mType = kTypeString;
|
||||
item->u.stringValue = new AString(s, len < 0 ? strlen(s) : len);
|
||||
}
|
||||
|
||||
void AMessage::setObject(const char *name, const sp<RefBase> &obj) {
|
||||
Item *item = allocateItem(name);
|
||||
item->mType = kTypeObject;
|
||||
|
||||
if (obj != NULL) { obj->incStrong(this); }
|
||||
item->u.refValue = obj.get();
|
||||
}
|
||||
|
||||
void AMessage::setMessage(const char *name, const sp<AMessage> &obj) {
|
||||
Item *item = allocateItem(name);
|
||||
item->mType = kTypeMessage;
|
||||
|
||||
if (obj != NULL) { obj->incStrong(this); }
|
||||
item->u.refValue = obj.get();
|
||||
}
|
||||
|
||||
bool AMessage::findString(const char *name, AString *value) const {
|
||||
const Item *item = findItem(name, kTypeString);
|
||||
if (item) {
|
||||
*value = *item->u.stringValue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AMessage::findObject(const char *name, sp<RefBase> *obj) const {
|
||||
const Item *item = findItem(name, kTypeObject);
|
||||
if (item) {
|
||||
*obj = item->u.refValue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AMessage::findMessage(const char *name, sp<AMessage> *obj) const {
|
||||
const Item *item = findItem(name, kTypeMessage);
|
||||
if (item) {
|
||||
*obj = static_cast<AMessage *>(item->u.refValue);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AMessage::post(int64_t delayUs) {
|
||||
extern ALooperRoster gLooperRoster;
|
||||
|
||||
gLooperRoster.postMessage(this, delayUs);
|
||||
}
|
||||
|
||||
sp<AMessage> AMessage::dup() const {
|
||||
sp<AMessage> msg = new AMessage(mWhat, mTarget);
|
||||
msg->mNumItems = mNumItems;
|
||||
|
||||
for (size_t i = 0; i < mNumItems; ++i) {
|
||||
const Item *from = &mItems[i];
|
||||
Item *to = &msg->mItems[i];
|
||||
|
||||
to->mName = from->mName;
|
||||
to->mType = from->mType;
|
||||
|
||||
switch (from->mType) {
|
||||
case kTypeString:
|
||||
{
|
||||
to->u.stringValue =
|
||||
new AString(*from->u.stringValue);
|
||||
break;
|
||||
}
|
||||
|
||||
case kTypeObject:
|
||||
case kTypeMessage:
|
||||
{
|
||||
to->u.refValue = from->u.refValue;
|
||||
to->u.refValue->incStrong(msg.get());
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
to->u = from->u;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
331
media/libstagefright/foundation/AString.cpp
Normal file
331
media/libstagefright/foundation/AString.cpp
Normal file
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ADebug.h"
|
||||
#include "AString.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
// static
|
||||
const char *AString::kEmptyString = "";
|
||||
|
||||
AString::AString()
|
||||
: mData((char *)kEmptyString),
|
||||
mSize(0),
|
||||
mAllocSize(1) {
|
||||
}
|
||||
|
||||
AString::AString(const char *s)
|
||||
: mData(NULL),
|
||||
mSize(0),
|
||||
mAllocSize(1) {
|
||||
setTo(s);
|
||||
}
|
||||
|
||||
AString::AString(const char *s, size_t size)
|
||||
: mData(NULL),
|
||||
mSize(0),
|
||||
mAllocSize(1) {
|
||||
setTo(s, size);
|
||||
}
|
||||
|
||||
AString::AString(const AString &from)
|
||||
: mData(NULL),
|
||||
mSize(0),
|
||||
mAllocSize(1) {
|
||||
setTo(from, 0, from.size());
|
||||
}
|
||||
|
||||
AString::AString(const AString &from, size_t offset, size_t n)
|
||||
: mData(NULL),
|
||||
mSize(0),
|
||||
mAllocSize(1) {
|
||||
setTo(from, offset, n);
|
||||
}
|
||||
|
||||
AString::~AString() {
|
||||
clear();
|
||||
}
|
||||
|
||||
AString &AString::operator=(const AString &from) {
|
||||
if (&from != this) {
|
||||
setTo(from, 0, from.size());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t AString::size() const {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
const char *AString::c_str() const {
|
||||
return mData;
|
||||
}
|
||||
|
||||
bool AString::empty() const {
|
||||
return mSize == 0;
|
||||
}
|
||||
|
||||
void AString::setTo(const char *s) {
|
||||
setTo(s, strlen(s));
|
||||
}
|
||||
|
||||
void AString::setTo(const char *s, size_t size) {
|
||||
clear();
|
||||
append(s, size);
|
||||
}
|
||||
|
||||
void AString::setTo(const AString &from, size_t offset, size_t n) {
|
||||
CHECK(&from != this);
|
||||
|
||||
clear();
|
||||
setTo(from.mData + offset, n);
|
||||
}
|
||||
|
||||
void AString::clear() {
|
||||
if (mData && mData != kEmptyString) {
|
||||
free(mData);
|
||||
mData = NULL;
|
||||
}
|
||||
|
||||
mData = (char *)kEmptyString;
|
||||
mSize = 0;
|
||||
mAllocSize = 1;
|
||||
}
|
||||
|
||||
size_t AString::hash() const {
|
||||
size_t x = 0;
|
||||
for (size_t i = 0; i < mSize; ++i) {
|
||||
x = (x * 31) + mData[i];
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
bool AString::operator==(const AString &other) const {
|
||||
return mSize == other.mSize && !memcmp(mData, other.mData, mSize);
|
||||
}
|
||||
|
||||
void AString::trim() {
|
||||
makeMutable();
|
||||
|
||||
size_t i = 0;
|
||||
while (i < mSize && isspace(mData[i])) {
|
||||
++i;
|
||||
}
|
||||
|
||||
size_t j = mSize;
|
||||
while (j > i && isspace(mData[j - 1])) {
|
||||
--j;
|
||||
}
|
||||
|
||||
memmove(mData, &mData[i], j - i);
|
||||
mSize = j - i;
|
||||
mData[mSize] = '\0';
|
||||
}
|
||||
|
||||
void AString::erase(size_t start, size_t n) {
|
||||
CHECK_LT(start, mSize);
|
||||
CHECK_LE(start + n, mSize);
|
||||
|
||||
makeMutable();
|
||||
|
||||
memmove(&mData[start], &mData[start + n], mSize - start - n);
|
||||
mSize -= n;
|
||||
mData[mSize] = '\0';
|
||||
}
|
||||
|
||||
void AString::makeMutable() {
|
||||
if (mData == kEmptyString) {
|
||||
mData = strdup(kEmptyString);
|
||||
}
|
||||
}
|
||||
|
||||
void AString::append(const char *s) {
|
||||
append(s, strlen(s));
|
||||
}
|
||||
|
||||
void AString::append(const char *s, size_t size) {
|
||||
makeMutable();
|
||||
|
||||
if (mSize + size + 1 > mAllocSize) {
|
||||
mAllocSize = (mAllocSize + size + 31) & -32;
|
||||
mData = (char *)realloc(mData, mAllocSize);
|
||||
CHECK(mData != NULL);
|
||||
}
|
||||
|
||||
memcpy(&mData[mSize], s, size);
|
||||
mSize += size;
|
||||
mData[mSize] = '\0';
|
||||
}
|
||||
|
||||
void AString::append(const AString &from) {
|
||||
append(from.c_str(), from.size());
|
||||
}
|
||||
|
||||
void AString::append(const AString &from, size_t offset, size_t n) {
|
||||
append(from.c_str() + offset, n);
|
||||
}
|
||||
|
||||
void AString::append(int x) {
|
||||
char s[16];
|
||||
sprintf(s, "%d", x);
|
||||
|
||||
append(s);
|
||||
}
|
||||
|
||||
void AString::append(unsigned x) {
|
||||
char s[16];
|
||||
sprintf(s, "%u", x);
|
||||
|
||||
append(s);
|
||||
}
|
||||
|
||||
void AString::append(long x) {
|
||||
char s[16];
|
||||
sprintf(s, "%ld", x);
|
||||
|
||||
append(s);
|
||||
}
|
||||
|
||||
void AString::append(unsigned long x) {
|
||||
char s[16];
|
||||
sprintf(s, "%lu", x);
|
||||
|
||||
append(s);
|
||||
}
|
||||
|
||||
void AString::append(long long x) {
|
||||
char s[32];
|
||||
sprintf(s, "%lld", x);
|
||||
|
||||
append(s);
|
||||
}
|
||||
|
||||
void AString::append(unsigned long long x) {
|
||||
char s[32];
|
||||
sprintf(s, "%llu", x);
|
||||
|
||||
append(s);
|
||||
}
|
||||
|
||||
void AString::append(float x) {
|
||||
char s[16];
|
||||
sprintf(s, "%f", x);
|
||||
|
||||
append(s);
|
||||
}
|
||||
|
||||
void AString::append(double x) {
|
||||
char s[16];
|
||||
sprintf(s, "%f", x);
|
||||
|
||||
append(s);
|
||||
}
|
||||
|
||||
void AString::append(void *x) {
|
||||
char s[16];
|
||||
sprintf(s, "%p", x);
|
||||
|
||||
append(s);
|
||||
}
|
||||
|
||||
ssize_t AString::find(const char *substring, size_t start) const {
|
||||
CHECK_LE(start, size());
|
||||
|
||||
const char *match = strstr(mData + start, substring);
|
||||
|
||||
if (match == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return match - mData;
|
||||
}
|
||||
|
||||
void AString::insert(const AString &from, size_t insertionPos) {
|
||||
insert(from.c_str(), from.size(), insertionPos);
|
||||
}
|
||||
|
||||
void AString::insert(const char *from, size_t size, size_t insertionPos) {
|
||||
CHECK_GE(insertionPos, 0u);
|
||||
CHECK_LE(insertionPos, mSize);
|
||||
|
||||
makeMutable();
|
||||
|
||||
if (mSize + size + 1 > mAllocSize) {
|
||||
mAllocSize = (mAllocSize + size + 31) & -32;
|
||||
mData = (char *)realloc(mData, mAllocSize);
|
||||
CHECK(mData != NULL);
|
||||
}
|
||||
|
||||
memmove(&mData[insertionPos + size],
|
||||
&mData[insertionPos], mSize - insertionPos + 1);
|
||||
|
||||
memcpy(&mData[insertionPos], from, size);
|
||||
|
||||
mSize += size;
|
||||
}
|
||||
|
||||
bool AString::operator<(const AString &other) const {
|
||||
return compare(other) < 0;
|
||||
}
|
||||
|
||||
bool AString::operator>(const AString &other) const {
|
||||
return compare(other) > 0;
|
||||
}
|
||||
|
||||
int AString::compare(const AString &other) const {
|
||||
return strcmp(mData, other.mData);
|
||||
}
|
||||
|
||||
void AString::tolower() {
|
||||
makeMutable();
|
||||
|
||||
for (size_t i = 0; i < mSize; ++i) {
|
||||
mData[i] = ::tolower(mData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bool AString::startsWith(const char *prefix) const {
|
||||
return !strncmp(mData, prefix, strlen(prefix));
|
||||
}
|
||||
|
||||
AString StringPrintf(const char *format, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
char *buffer;
|
||||
vasprintf(&buffer, format, ap);
|
||||
|
||||
va_end(ap);
|
||||
|
||||
AString result(buffer);
|
||||
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
35
media/libstagefright/foundation/Android.mk
Normal file
35
media/libstagefright/foundation/Android.mk
Normal file
@@ -0,0 +1,35 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES:= \
|
||||
AAtomizer.cpp \
|
||||
ABuffer.cpp \
|
||||
ADebug.cpp \
|
||||
ALooper.cpp \
|
||||
ALooperRoster.cpp \
|
||||
AMessage.cpp \
|
||||
AString.cpp \
|
||||
base64.cpp \
|
||||
hexdump.cpp
|
||||
|
||||
LOCAL_C_INCLUDES:= \
|
||||
frameworks/base/include/media/stagefright/foundation
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libbinder \
|
||||
libmedia \
|
||||
libutils \
|
||||
libcutils \
|
||||
libui \
|
||||
libsonivox \
|
||||
libvorbisidec \
|
||||
libsurfaceflinger_client \
|
||||
libcamera_client
|
||||
|
||||
LOCAL_CFLAGS += -Wno-multichar
|
||||
|
||||
LOCAL_MODULE:= libstagefright_foundation
|
||||
|
||||
LOCAL_PRELINK_MODULE:= false
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
139
media/libstagefright/foundation/base64.cpp
Normal file
139
media/libstagefright/foundation/base64.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "base64.h"
|
||||
|
||||
#include "ABuffer.h"
|
||||
#include "ADebug.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
sp<ABuffer> decodeBase64(const AString &s) {
|
||||
if ((s.size() % 4) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t n = s.size();
|
||||
size_t padding = 0;
|
||||
if (n >= 1 && s.c_str()[n - 1] == '=') {
|
||||
padding = 1;
|
||||
|
||||
if (n >= 2 && s.c_str()[n - 2] == '=') {
|
||||
padding = 2;
|
||||
}
|
||||
}
|
||||
|
||||
size_t outLen = 3 * s.size() / 4 - padding;
|
||||
|
||||
sp<ABuffer> buffer = new ABuffer(outLen);
|
||||
|
||||
uint8_t *out = buffer->data();
|
||||
size_t j = 0;
|
||||
uint32_t accum = 0;
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
char c = s.c_str()[i];
|
||||
unsigned value;
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
value = c - 'A';
|
||||
} else if (c >= 'a' && c <= 'z') {
|
||||
value = 26 + c - 'a';
|
||||
} else if (c >= '0' && c <= '9') {
|
||||
value = 52 + c - '0';
|
||||
} else if (c == '+') {
|
||||
value = 62;
|
||||
} else if (c == '/') {
|
||||
value = 63;
|
||||
} else if (c != '=') {
|
||||
return NULL;
|
||||
} else {
|
||||
if (i < n - padding) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
value = 0;
|
||||
}
|
||||
|
||||
accum = (accum << 6) | value;
|
||||
|
||||
if (((i + 1) % 4) == 0) {
|
||||
out[j++] = (accum >> 16);
|
||||
|
||||
if (j < outLen) { out[j++] = (accum >> 8) & 0xff; }
|
||||
if (j < outLen) { out[j++] = accum & 0xff; }
|
||||
|
||||
accum = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static char encode6Bit(unsigned x) {
|
||||
if (x <= 25) {
|
||||
return 'A' + x;
|
||||
} else if (x <= 51) {
|
||||
return 'a' + x - 26;
|
||||
} else if (x <= 61) {
|
||||
return '0' + x - 52;
|
||||
} else if (x == 62) {
|
||||
return '+';
|
||||
} else {
|
||||
return '/';
|
||||
}
|
||||
}
|
||||
|
||||
void encodeBase64(
|
||||
const void *_data, size_t size, AString *out) {
|
||||
out->clear();
|
||||
|
||||
const uint8_t *data = (const uint8_t *)_data;
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < (size / 3) * 3; i += 3) {
|
||||
uint8_t x1 = data[i];
|
||||
uint8_t x2 = data[i + 1];
|
||||
uint8_t x3 = data[i + 2];
|
||||
|
||||
out->append(encode6Bit(x1 >> 2));
|
||||
out->append(encode6Bit((x1 << 4 | x2 >> 4) & 0x3f));
|
||||
out->append(encode6Bit((x2 << 2 | x3 >> 6) & 0x3f));
|
||||
out->append(encode6Bit(x3 & 0x3f));
|
||||
}
|
||||
switch (size % 3) {
|
||||
case 0:
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
uint8_t x1 = data[i];
|
||||
uint8_t x2 = data[i + 1];
|
||||
out->append(encode6Bit(x1 >> 2));
|
||||
out->append(encode6Bit((x1 << 4 | x2 >> 4) & 0x3f));
|
||||
out->append(encode6Bit((x2 << 2) & 0x3f));
|
||||
out->append('=');
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
uint8_t x1 = data[i];
|
||||
out->append(encode6Bit(x1 >> 2));
|
||||
out->append(encode6Bit((x1 << 4) & 0x3f));
|
||||
out->append("==");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
73
media/libstagefright/foundation/hexdump.cpp
Normal file
73
media/libstagefright/foundation/hexdump.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "hexdump.h"
|
||||
|
||||
#include "ADebug.h"
|
||||
#include "AString.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
void hexdump(const void *_data, size_t size) {
|
||||
const uint8_t *data = (const uint8_t *)_data;
|
||||
|
||||
size_t offset = 0;
|
||||
while (offset < size) {
|
||||
AString line;
|
||||
|
||||
char tmp[32];
|
||||
sprintf(tmp, "%08lx: ", (unsigned long)offset);
|
||||
|
||||
line.append(tmp);
|
||||
|
||||
for (size_t i = 0; i < 16; ++i) {
|
||||
if (i == 8) {
|
||||
line.append(' ');
|
||||
}
|
||||
if (offset + i >= size) {
|
||||
line.append(" ");
|
||||
} else {
|
||||
sprintf(tmp, "%02x ", data[offset + i]);
|
||||
line.append(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
line.append(' ');
|
||||
|
||||
for (size_t i = 0; i < 16; ++i) {
|
||||
if (offset + i >= size) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (isprint(data[offset + i])) {
|
||||
line.append((char)data[offset + i]);
|
||||
} else {
|
||||
line.append('.');
|
||||
}
|
||||
}
|
||||
|
||||
LOG(INFO) << line;
|
||||
|
||||
offset += 16;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
Reference in New Issue
Block a user